Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perform the Pending Writes When the App is Closed

Firestore does not seem to perform the pending writes when the app is closed (killed by the system or removed by the user). Every write that is enqueued when the app is offline will be performed only when the app is online and running again.

I'd like to perform those writes manually in the background, so I'm using a Work Mananger which includes this line of code:

FirebaseFirestore.getInstance().enableNetwork();

Full snippet:

public class FirebaseSyncWorker extends Worker {

    public FirebaseSyncWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {

        FirebaseFirestore.getInstance().enableNetwork();

        return Result.success();
    }
}

This code works for me. It does sync user's data once in a while when the app is closed. However, I'm not sure if this is the proper way to do this.

As far as I know, enableNetwork() is intended to re-enable network access after disabling it. My app never disables it, I just use it to perform the pending writes.

Is this a good way to achieve what I want? Is there a better way to do this?

like image 943
Tal Barda Avatar asked Apr 26 '19 09:04

Tal Barda


People also ask

Can firebase work offline?

By enabling persistence, any data that the Firebase Realtime Database client would sync while online persists to disk and is available offline, even when the user or operating system restarts the app. This means your app works as it would online by using the local data stored in the cache.


1 Answers

enableNetwork() is a pretty clever way to do this. It hadn't been intended for this use, but it works.

The reason why is that enableNetwork() is designed to be idempotent. You can call it as often as you want and if the network is already enabled it does nothing. (disableNetwork() has the same kind of behavior.)

The other part of why this works is that Firestore does not start its internal work queue until you do something with it. We do this for a number of reasons, but principally this is to allow you to call setFirestoreSettings() before we do anything.

Your solution works because enableNetwork() is a call that triggers this internal startup, but then ultimately doesn't do anything because the network is already enabled.

Note that Firestore doesn't actually create a network connection if it doesn't have anything to do, so it's relatively cheap to start it up as you're doing and if there's nothing to do, it will check for pending writes and do nothing.

You could improve on this if there were an API to be able to know if we're done syncing pending writes. We've kicked this idea around but haven't settled on the API we want and haven't been able to prioritize this against other work. If this were very important to you, note that the source is open over at https://github.com/firebase/firebase-android-sdk/ and we're very friendly :-).

Update 2020-06-12: We added waitForPendingWrites which lets you wait until pending writes have finished.

like image 143
Gil Gilbert Avatar answered Sep 20 '22 23:09

Gil Gilbert