James Campbell James Campbell - 1 month ago 6x
iOS Question

What actually happens when persistence is enabled in Firebase?

When turning on persistence for Firebase in iOS what actually happens to my observers and how they behave on a technical level?

I have a good idea how it should work on a high-level based on this https://www.firebase.com/docs/ios/guide/offline-capabilities.html - Firebase essentially keeps a cached copy of the data you can access whilst offline.

What I don't understand is how many times my observers should fire and with what information.

  • Does firebase always trigger my observers once with any cached data first (or null if there isn't any data followed by the server data.

  • Or does it only send the cached data if it exists followed by the server data.

  • Is there any difference between observerSingleValue and a continous observer's behaviour when in persistence mode ?

In our app with persistence enabled, I have noticed:

  • Firebase just sending the server data

  • Firebase sending the cached data if it exists then the server data.

  • Firebase sending the cached data and null if it doesn't exist followed by the server data.

It would be good to clear this up so we know which should be the normal behaviour :)


It's actually pretty simple. When you attach an observer (whether using observeEventType or observeSingleEventOfType), Firebase will:

  1. Immediately raise events with any complete cached data.
  2. Request updated data from the server and, when it arrives, raise new events if the data is different than what was cached.

There are a couple subtleties that fall out of this though:

  • We'll only raise events with cached data if it is complete. This means:
    • If we have no cached data (you haven't observed this location before), we will not raise events with null or similar. You won't get any events until we get data from the server.
    • If you have partial data for this location (e.g. you observed /foo/bar previously but now you're observing /foo), you will get ChildAdded events for complete children (e.g. /foo/bar), but you won't get a Value event (e.g. for /foo) until we've gotten complete data from the server for the location you're observing.
  • If you're using observeSingleEventOfType, you're explicitly asking for only a single event and so if you have cached data, #1 will happen but #2 will not, which may not be what you want (you'll never see the latest server data).

Hope this helps!