Firebase:Differencebetween Setpersistenceenabled and Keepsynced

What is the difference between setPersistenceEnabled and keepSynced on Firebase?

setPersistenceEnabled(true) and keepSynced(true) do two different things.

setPersistenceEnabled(true) turns on disk caching of query results. Whenever possible, cached results will be used instead of fetching them from the server again.

keepSynced(true) is the exact same thing as adding a listener to the same location, and not removing it. So, whenever updates are available to that location, the SDK will download them and invoke any other listeners that are interested in that data.

Whether or not you should use either one of them is dependent on whether or not you want their stated purpose. Their functionalities don't overlap, except in that if both are enabled, any updates for the keepSynced location are also cached on disk, which just logical when you add up their functionalities.

Will the data redownloaded from firebase database if I am using keepSynced and setPersistenceEnabled true

The data will be returned from cache for queries where the data from the server is unchanged since it was saved in the cache.

The data will be removed from cache when the cache exceeds 10 MB and the data hasn't been used recently. (I believe it's an LRU cache.)

Firebase syncing method not syncing

Right now you're just telling Firebase to keep an empty listener active on your Friends and UserData nodes. This ensures that the data from these nodes is always kept up to date (even when you don't attach any other listeners), but the data is still only kept in memory.

To persist the memory cache to disk, so that it can be reloaded in case you don't have an internet connection when starting the app, you'll need to call FirebaseDatabase.getInstance().setPersistenceEnabled(true) when the app starts. See enabling disk persistence in the Firebase docs.

Also see:

  • Firebase : What is the difference between setPersistenceEnabled and keepSynced?

Firebase Offline Capabilities and addListenerForSingleValueEvent

Update (2021): There is a new method call (get on Android and getData on iOS) that implement the behavior you'll like want: it first tries to get the latest value from the server, and only falls back to the cache when it can't reach the server. The recommendation to use persistent listeners still applies, but at least there's a cleaner option for getting data once even when you have local caching enabled.



How persistence works

The Firebase client keeps a copy of all data you're actively listening to in memory. Once the last listener disconnects, the data is flushed from memory.

If you enable disk persistence in a Firebase Android application with:

Firebase.getDefaultConfig().setPersistenceEnabled(true); 

The Firebase client will keep a local copy (on disk) of all data that the app has recently listened to.

What happens when you attach a listener

Say you have the following ValueEventListener:

ValueEventListener listener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println(snapshot.getValue());
}

@Override
public void onCancelled(FirebaseError firebaseError) {
// No-op
}
};

When you add a ValueEventListener to a location:

ref.addValueEventListener(listener); 
// OR
ref.addListenerForSingleValueEvent(listener);

If the value of the location is in the local disk cache, the Firebase client will invoke onDataChange() immediately for that value from the local cache. If will then also initiate a check with the server, to ask for any updates to the value. It may subsequently invoke onDataChange() again if there has been a change of the data on the server since it was last added to the cache.

What happens when you use addListenerForSingleValueEvent

When you add a single value event listener to the same location:

ref.addListenerForSingleValueEvent(listener);

The Firebase client will (like in the previous situation) immediately invoke onDataChange() for the value from the local disk cache. It will not invoke the onDataChange() any more times, even if the value on the server turns out to be different. Do note that updated data still will be requested and returned on subsequent requests.

This was covered previously in How does Firebase sync work, with shared data?

Solution and workaround

The best solution is to use addValueEventListener(), instead of a single-value event listener. A regular value listener will get both the immediate local event and the potential update from the server.

A second solution is to use the new get method (introduced in early 2021), which doesn't have this problematic behavior. Note that this method always tries to first fetch the value from the server, so it will take longer to completely. If your value never changes, it might still be better to use addListenerForSingleValueEvent (but you probably wouldn't have ended up on this page in that case).

As a workaround you can also call keepSynced(true) on the locations where you use a single-value event listener. This ensures that the data is updated whenever it changes, which drastically improves the chance that your single-value event listener will see the current value.



Related Topics



Leave a reply



Submit