1

1 Suppose that i am doing something like following

FirestoreDatabase.getInstance()
                 .collection("users")
                 .add(userData); // where userData is reference to UserData object which contains many fileds 

Now if i am showing that data in recyclerview , the client library will show that immediately in recyclerview even before it is saved in firestore database to keep my app more responsive.

So when the data shows up in the recyclerview the user thinks he successfully added the data BUT what happens if the write request fails when the data reach the firestore , will the onFailure listner trigger and as the data already in the UI before actual write wil the data disappear from the UI ?

2 When the user is offline he can still use the app and add the data and shows up in UI for user it means he successfully added the data then whey onSuccessListener gets triggered only when the user is online.

ex supposein successlistener in am displaying a toast saying data added but user only sees it when he is online , when he is offline he can see the data in UI but not toast and thinks why toast didn't show up this time.

Abhinav Chauhan
  • 1,304
  • 1
  • 7
  • 24

3 Answers3

2

The onSuccessListener will trigger even if the user is offline because by default, the change is made locally. If it can't be persisted online immediately, the app will try again when a connection is available. This is explained here: Access Data Offline

Cloud Firestore supports offline data persistence. This feature caches a copy of the Cloud Firestore data that your app is actively using, so your app can access the data when the device is offline. You can write, read, listen to, and query the cached data. When the device comes back online, Cloud Firestore synchronizes any local changes made by your app to the Cloud Firestore backend.

I don't know what situation you mean other than a network connection being unavailable for the data failing to be saved to the database, but the database will be cached locally so any conflicts should occur locally too.

EDIT: Fundamentally, if the data would fail to go into the database for any reason other than waiting for an internet connection, it won't appear in the UI which is being populated from the database, so you don't need to worry about things disappearing later.

notquiteamonad
  • 1,159
  • 2
  • 12
  • 28
  • in my onSucessListerer is triggering only user is online, i tried showing a toast in listener , i added the data while mobile data was off the data appear in UI, then i turned on the mobile data , and then the toast appeared – Abhinav Chauhan Apr 10 '20 at 11:29
  • In that case perhaps the task only resolves once the offline persistence is done, but any failures other than due to connection failure would prevent the local copy being modified, so they wouldn't show up in the UI at all if they would fail (assuming your UI is being populated by a watcher on the collection) – notquiteamonad Apr 10 '20 at 11:33
  • @AbhinavChauhan I've added an edit at the bottom of my answer to answer this - basically you don't need to worry about that case because they would fail locally if they would fail locally – notquiteamonad Apr 10 '20 at 11:36
  • how does it know offline if i am violating any security rule or exceeding some write limit, because in these cases write may fail, i my app data shows up in UI but doesn't get into database because of security rule – Abhinav Chauhan Apr 10 '20 at 11:42
  • I believe that's all part of the cache, so can also be checked offline. – notquiteamonad Apr 10 '20 at 11:44
  • in my app data is added in UI but fails to added in firestore because of security rule now when i open some other activity on top of where data was shown , that data disappears – Abhinav Chauhan Apr 10 '20 at 11:47
  • Security should be enforced both by the database (through your security rules) and through your user interface. It shouldn't be possible for the user to use your app in a way which allows them to perform an operation which will fail against a security rule; hide that option from them in an app or perform a check before adding the item into the database. – notquiteamonad Apr 10 '20 at 11:57
  • thanks for suggestion but write can fail for many reasons like exceeding some limit , i can't check everything – Abhinav Chauhan Apr 10 '20 at 12:05
  • @AbhinavChauhan surely these are very much edge cases though? Unfortunately it seems you have three options. 1) Check every case. 2) Don't check every case, pick some and allow the occasional error. Or 3) disable offline persistence and require an internet connection to mitigate these errors – notquiteamonad Apr 10 '20 at 12:08
2

BUT what happens if the write request fails

It means that don't have access to write that data. onFailure() is only executed when there was a problem with writing the document, meaning the write operation is rejected.

When the user is offline he can still use the app and add the data and shows up in UI

This is happening because, for Android and iOS, offline persistence is enabled by default.

onSuccessListener gets triggered only when the user is online.

Yes, onSuccessListener() gets triggered only when the write operation is successful, meaning the operation is written on Firebase servers.

upposein successlistener in am displaying a toast saying data added but user only sees it when he is online , when he is offline he can see the data in UI but not toast and thinks why toast didn't show up this time.

The user won't be notified with that toast, because that data is not yet added on the server.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • yes he won't be notified with toast when he is offline , but user don't understand the offline persistence he will think why there is a toast sometime and not other times, another thing is in my app data shows up in UI but fails to write in database because of security rules, but if it appears in UI my user will think he successfully added the data – Abhinav Chauhan Apr 10 '20 at 11:45
  • In that case, check for internet connection before doing some operations. In that way, the user will not be notified without purpose. If the write fails, then make sure you have set the correct rules. – Alex Mamo Apr 10 '20 at 11:48
  • yes but checking the internet connection defeats the purpose of offline support – Abhinav Chauhan Apr 10 '20 at 11:52
  • No, checking for internet connection will help you know when you can notify the user or not. – Alex Mamo Apr 10 '20 at 11:53
  • onSuccessLister only gets trigger when user is online so why would i check – Abhinav Chauhan Apr 10 '20 at 11:55
  • You check for internet connection before you do some operations, otherwise, you do the operations and the Toast will be displayed some time later, and I understand that it is not what you want, right? – Alex Mamo Apr 10 '20 at 11:57
  • yes and whole point of using listener is making sure data gets added , and if the data shows in UI before any listener gets executed , from client perspective showing data in UI means data was added , but data might not be added due to some failure and next time he opens the data will not showup in UI and he will not have any idea , what happend – Abhinav Chauhan Apr 10 '20 at 12:03
  • In that case, make sure you always have the correct rules so your writes never fail. – Alex Mamo Apr 10 '20 at 12:04
  • thanks for suggestion but write can fail for many reasons like exceeding some limit , i can't make sure everything, or like if i change security rules to false because i found i will be billed too much , but from users perspective they are still adding the data, if they are offline they don't get latest security rules and data will show up in UI – Abhinav Chauhan Apr 10 '20 at 12:06
  • In that case, try to read all limitations that you might exceed and make sure you stay under them. – Alex Mamo Apr 10 '20 at 12:10
  • yes but if i have to make sure everything should work without failure , then why would i use a listner if i know i made sure everything will work , and i can show the toast right away. I know i may start sounding annoying but i am just curious. – Abhinav Chauhan Apr 10 '20 at 12:21
  • Everything in Firebase it's about listeners. Without using, you'll never know if your write fails or not. Even if you make sure everything should work without failure, you cannot be 100% sure about it. – Alex Mamo Apr 10 '20 at 12:41
  • hmm that was helpful , i appreciate you took time to clear doubts to extent they could be cleared. And if i take care of security, and limits the failure can occur rarely like once on a year, the app can misbehave once in a year what say? – Abhinav Chauhan Apr 11 '20 at 02:20
  • No, I say that you should search for all situations in which your app can fail and try to avoid them. It's best to avoid also that failure that can happen even once in a year. – Alex Mamo Apr 11 '20 at 10:09
  • 1
    Ok sir, i shall remember – Abhinav Chauhan Apr 11 '20 at 11:44
0

This is because Firestore data is locally persisted by default. Therefore if you save data in Firestore it saves it in the local database. And later on when the internet will be available it'll be synced with the server.

If you want to get rid of that use this line before any operation takes place in application. More suitable place is Application class.

FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
        .setPersistenceEnabled(true)
        .build();
db.setFirestoreSettings(settings);

After adding these lines the data fail to save in Firestore if an internet connection is not available.

notquiteamonad
  • 1,159
  • 2
  • 12
  • 28
Abdur Rahman
  • 894
  • 1
  • 11
  • 27
  • If you want to disable it you want to change the `true` to `false` in `setPersistenceEnabled`. – notquiteamonad Apr 10 '20 at 11:21
  • no i want to do it offline my first question is data can be added successfully offline and show up in UI , but what if user get back online and a the firestore reject to save the data. – Abhinav Chauhan Apr 10 '20 at 11:31
  • If it saved locally then failure can't happen. It will be saved remotely on server without any error. – Abdur Rahman Apr 11 '20 at 05:45