29

I thought the whole time when I used the following all data for chat conversation will be available offline at any time. Which somehow isn't and all nodes are loaded from the server.

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

Then, according to DOCS :

Persistence Behavior : By enabling persistence, any data that we sync while online will be persisted to disk and available offline, even when we restart the app. This means our app will work as it would online using the local data stored in the cache.

If data will already be available offline when setPersistenceEnabled(true); , why do I need keepSynced(true) ?

DatabaseReference r = FirebaseDatabase.getInstance().getReference("chat/roomid");
r.keepSynced(true);
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Relm
  • 7,923
  • 18
  • 66
  • 113

3 Answers3

34

The Firebase Database client in your app can keep the data from the database in two places: in memory and/or on disk.

  1. When you attach a listener, it synchronizes data from the database to an in memory representation in your app.
  2. If you've enable persistence, the data is automatically also persisted on disk.
  3. When you detach the last listener from a location, the data for that location is flushed from memory. But it is not deleted from disk.

When you keep a location synchronized, the client essentially attaches an empty listener to that location. So the data in the app will always be up to date with what's in the database on the server (as long as there is a network connection). If you haven't enabled persistence, the data will just be kept up to date in memory. If you've enabled persistence, it will also be kept up to date on disk.

While it's most common to use keepSynced with persistence, there are also use-cases without persistence.

For example, if you have a master-detail app, where you frequently bounce from a list of item names to the details of each item. In that case keeping the list of item names synchronized will save you from having to reload that data when the user comes back from the detail screen.

You could of course also simply keep a listener on the data, which is essentially what keepSynced does behind the scenes.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • FirebaseDatabase.getInstance().setPersistenceEnabled(true); doesn't make chat available for offline – Maveňツ Feb 03 '17 at 07:47
  • @maveň, check the answer below and my clarification on it. – mradzinski Apr 17 '17 at 02:57
  • 1
    @Frank van Puffelen if persistence is enabled and the app is terminated, then next time the app runs does Firebase copy over the entire database from the server to memory and disk, or does it just copy those items from the server which have changed? I.e. it can tell what is the delta between the data on device disk and the data in the server and only move the delta data to the handset? – Gruntcakes Jan 04 '18 at 02:14
  • For how long will the data persist in the disk? Till the app gets uninstalled? Is there any way to explicitly delete the data from the disk? What is the advantage of doing this? – Sreekanth Karumanaghat Mar 05 '18 at 07:36
  • You explained a scenario where keeySync is usefull, can you also explain a scenario where setPersistenceEnabled is usefull in a similar way. – Sreekanth Karumanaghat Mar 05 '18 at 07:39
  • Sorry for the stupid question. But what exactly is the `The Firebase Database client in your app`. Is this user, or the code that I have written in my app? – CopsOnRoad Mar 14 '18 at 06:27
  • "You could of course also simply keep a listener on the data, which is essentially what keepSynced does behind the scenes." I think I finally understood what it is. – Henrique Bruno Dec 21 '20 at 01:15
4

According to Firebase documentation

By default the Firebase client will keep data in memory while your application is running, but not when it is restarted. By setting this value to true, the data will be persisted to on-device (disk) storage and will thus be available again when the app is restarted (even when there is no network connectivity at that time). Note that this method must be called before creating your first Firebase reference and only needs to be called once per application. If your app uses Firebase Authentication, the client will automatically persist the user's authentication token across restarts, even without persistence enabled. But if the auth token expired while offline and you've enabled persistence, the client will pause write operations until you successfully re-authenticate (or explicitly call unauth) to prevent your writes from being sent unauthenticated and failing due to security rules.

Note that it says the data will persist on disk and be available when apps restart. If you look at the life cycle of an Activity, you'll see that an activity stop when you change to other activity. So, as long as your app is still open and user only navigated to others activities, data will remain persisted.

But don't say anything about killing your app and persist data. That's why you need keepSynced():

By calling keepSynced(true) on a location, the data for that location will automatically be downloaded and kept in sync, even when no listeners are attached for that location. Additionally, while a location is kept synced, it will not be evicted from the persistent disk cache.

Pay attencion when it says "while location is kept synced, it will not be evicted from the persistent disk cache", this means that if you don't use keepSynced(true) your data could be flushed way when the app is killed/closed.

So, to persist and continue with data after your app is killed, you need to use both FirebaseDatabase.getInstance().setPersistenceEnabled(true); and keepSynced(true).

spassador
  • 393
  • 1
  • 12
Smaily Carrilho
  • 131
  • 2
  • 12
  • 2
    Just to clarify on this: ```keepSynced(true)``` should be invoked from those references that you require to keep in sync (unless your requirement states that you wanna keep your whole database device-synced). In other words, if you have a structure like ```users/{userUID}/tasks``` and you want to keep the tasks synced then you should invoke ```keepSynced(true)``` when referencing that path. – mradzinski Apr 17 '17 at 02:55
3

setPersistanceEnabled(true) It will store the data for offline use.

keepsynced(true) by default, Firebase keeps 10mb data in cache,if it grows further it will replace by new data.To avoid the same and keep the whole data keepsynced(true) will help You.

SAJI S A
  • 39
  • 1