1

I am wondering if IndexedDB is the only cache Firestore uses.

To be clear, I am not talking about persisting data with enableIndexedDbPersistence(). I am talking about an internal store for the sole purpose of optimistic updates when the app is still in state. Is there something similar to redux, svelte store, or InMemoryCache which is run in the background when a subscription is open?

It seems that when I use onSnapShot() for a list of items, and I update an item in the list with setDoc elsewhere, the UI gets updated immediately, optimistically.

Perhaps Firestore is just that quick where the data is sent to the server, changed, and sent back to the client with the UI being updated that quickly, but it seems to me it is an optimistic update.

Does Firestore use any other caching techniques or state management techniques when the app is still running besides IndexedDB?

J

References (maybe releated):

Jonathan
  • 3,893
  • 5
  • 46
  • 77

1 Answers1

2

As long as you have an active onSnapShot listener, the Firestore SDK will have a copy of the latest query snapshot for that listener in memory. If you attach another listener to the same (or partially overlapping) data, that listener may get (part of) its data from the existing listener.

So when you perform an update in the same client as where you have a listener, the SDK immediately applies that update to its local copy of the data and fires an event (so that is almost instantly). It then sends the update to the server, which executes it on the backend storage layer. If that update gets rejected (a relatively rare occurrence), the client will revert the change it make locally and fire another event with the corrected state.

An easy way to see this in practice is to perform a write operation that is rejected by your security rules. You'll briefly see the invalid state on the client, before it reverts to the correct state. This invalid state only happens on the client that performs the invalid write, so it's typically fine to ignore it there.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Frank, is this documented anywhere so that I can understand more about this process? – Jonathan Sep 07 '22 at 21:48
  • 1
    "this" is a bit broad there, but the optimistic client-side events used to be described as "local writes in your app will invoke snapshot listeners immediately." Funnily enough I can now only find that phrasing in the context of Firestore, where it most definitely was in RTDB years before we released Firestore. :) --- There's still some docs here: https://firebase.google.com/docs/database/admin/save-data#section-writes-offline and here: https://firebase.google.com/docs/database/web/read-and-write#work_with_data_offline – Frank van Puffelen Sep 07 '22 at 22:29
  • Frank could this be the cause of an observable firing twice? When I write directly to Firestore my observable emits once as expected, but when I post something to Firestore my observable is emitting (the same data) twice. My thought being that the local write is causing the observable to fire, but when the data gets written to Firestore and comes back to my app the observable fires a second time. – Tim Thompson Dec 12 '22 at 22:59