0

I understand that snapshot listeners for a document incur a read on creation and when activated / providing data.

Is this also the case when the activation is triggered by a local write to the document (where, I think, the data is bounced back to the listener within the client and data is not returned from the server because there's no difference)?

i.e. If you add a snapshot listener to a document being edited locally 99% of the time, are you now on the hook for, at minimum, the same number of reads as writes?

Ian
  • 592
  • 5
  • 21

1 Answers1

2

If you add a snapshot listener to a document being edited locally 99% of the time, are you now on the hook for, at minimum, the same number of reads as writes?

A listener does not charge for document writes. It only charges for changes to documents read by the query.

Highly likely, though not absolutely certain, that all writes you make to a document will end up charging a read to an active listener on that document, as each write hits the server, then causes a callback to the listener with that change. You should be prepared to accept that cost.

If a client app is offline during the write, you will not be charged for the immediate listener callback. It only incurs a charge when the updated document is actually retrieved from the server.

You might want to debounce document writes if you wish to reduce the read cost.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • It appears my question is effectively a duplicate of this: https://stackoverflow.com/questions/55919435/do-local-writes-to-firebase-rtdb-or-firestore-with-attached-listeners-cost-a-rea But the short answer there is a 'no' -- a listener triggered by local updates will not incur a read. However, after running a test w/ repeating writes and a snapshot listener (1) the same number of reads and writes are logged in the console (2) but the metadata.fromCache I receive in the listener is only true in the first couple writes and 'false' thereafter... so I think I've lost the thread somewhere... – Ian Aug 24 '20 at 18:33
  • "as each write hits the server, then causes a callback to the listener with that change." This does exactly align what what I understand for this official description: https://www.youtube.com/watch?v=3aoxOtMM2rc&t=4m12s – Ian Aug 24 '20 at 18:39
  • Without seeing your code and observing the results, there's not much else I can add. – Doug Stevenson Aug 24 '20 at 19:39
  • Apologies, I should've said: It appears your answer conflicts with the answer of a potentially duplicate question and it may be worth chiming in over there -- I may delete this one shortly. Also, I've split out a second question around my tests with example code here: https://stackoverflow.com/questions/63567410/onsnapshot-fromcache-always-false-when-change-is-local – Ian Aug 24 '20 at 19:55
  • 1
    I don't see that there's a conflict. I make a distinction between the non-cost of an *immediate* trigger (which will happen while offline, so no billing could even occur) vs. the cost of an *eventual* full read that always happens while only that occurs due to synchronization. – Doug Stevenson Aug 24 '20 at 20:04
  • I think I see; I may have been thrown by statements on that thread like "In case the data does not come from the server (is coming from the cache), there is no cost." It was my (mistaken?) understanding that a response from the server that effectively matches the cache is swallowed -- not passed to onSnapshot -- such that when a local change triggers onSnapshot, the handler receives data that is essentially 'from the cache'. – Ian Aug 24 '20 at 20:34
  • 1
    If a synchronized snapshot from the server is no different than a snapshot previously delivered from the cache, then there will not be another callback - the app already has the most recent data. But that doesn't mean that the synchronization was free. If you want to get a callback for both the local change and the eventual change from the server, in order to distinguish between the two, you will have to ask the listener to give you metadata updates. – Doug Stevenson Aug 24 '20 at 20:43