13

I have been writing an app using the new cloud firestore database. It works great except the fact that many things are not working smoothly when offline although the offline persistence is enabled. For instance I do the following:

ref.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    //Do something
                } else {
                    //Do another thing
                }

            }
        });

However the onComplete method is never called when offline. I want to close the activity and show some Snachbar once this happens. But as it never does, the activity remains open. I am using android studio emulator.

Thanks

edmond
  • 833
  • 3
  • 13
  • 31

1 Answers1

14

Operations that write to the database are defined to signal completion once they've actually committed to the backend. As a result this is working as intended: while offline they won't signal completion.

Note that the Firestore clients internally guarantee that you can read your own writes even if you don't wait for completion of the task from delete.

For the most part this means that you shouldn't need to wait for this task to complete. Is there any particular reason you're interested in doing so?

Gil Gilbert
  • 7,722
  • 3
  • 24
  • 25
  • Hi @Gil Gilbert. I wasn't aware that the completion was meant for the backend. I will adjust my code. Thanks. – edmond Oct 10 '17 at 19:12
  • Does the same apply to onSuccess and on Failure? – 34m0 Nov 01 '17 at 12:50
  • Yes. No completion, success, or failure handler will be invoked until the task completes. The task won't complete until the write is committed to the backend. – Gil Gilbert Nov 01 '17 at 20:48
  • 12
    This is a big problem, because it means you can't chain tasks together when offline. There also seems to be no way to get the document id for a new document when offline, because the listener will not complete. This is different from firebase, where you could make a bunch of local changes and they would sync when online. – Dutch Masters Dec 15 '17 at 19:57
  • This is essentially the same as the RTDB, which similarly does not complete writes until they've committed to the server. The id of a newly written document is available immediately--you don't have to wait for it. Similarly, you can just assume the write has completed while offline--any subsequent read will see it immediately. Unless you specifically care writes completing at the server, don't wait for completion. – Gil Gilbert Dec 19 '17 at 02:14
  • 1
    Talking about a particular reason why this would be helpful. Usually we need to let user know that his/her data was saved successfully. It would be quite useful to have the ability to distinguish the following cases: 1) data saved to offline cache 2) data saved to server 3) server returned an error while saving (access rights, limits etc.). Or the ability to force saving data to server (or error if impossible) - to let user know that his/her data is on the cloud and could be available later from an other device for ex. – algrid May 30 '19 at 12:04
  • 1
    1) happens automatically. Your next read will see the value guaranteed. 2) is what's signaled by task completion. 3) is surfaced as a non-successful task. 4) use a Transaction to force saving to the server. Transactions are online only and will fail if they can't communicate with the server. – Gil Gilbert Jun 11 '19 at 15:38
  • @GilGilbert After scratching my head why document snapshot listeners were not triggered when using "update" when offline I discovered that I was updating using a transaction. – Mark Feb 14 '21 at 14:40
  • @Dutch Masters it is possible to get document id of new document when offline. Instead of using add method create an empty document , then u get its id and then use set method to put and object inside document look example below: val docRef = db.collection("COLLECTION_NAME").document() , val id = docRef.id // so now u can use the id else where , docRef.set(put ur actual object here) – Njuacha Hubert Nov 29 '21 at 21:19