-
Notifications
You must be signed in to change notification settings - Fork 428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question] "Out of sync" data in Firestore #1083
Comments
Hi @Nyankoo. A quick Google search for that quote lead me to this article: https://medium.com/firebase-developers/firestore-clients-to-cache-or-not-to-cache-or-both-8f66a239c329. Is this where you copied that quote from? Assuming it is, I believe you are asking if writes made while offline will eventually be sync'd to the backend when the app goes back online, even if interrupted by an app restart. If that is your question then the answer is "yes". Although the promise/task/callback initially attached to the write operation no longer exist after the app is restarted, the write is recorded in the local cache and will be sync'd with the backend once connectivity is restored. Does this answer your question? |
Hi @dconeybe, thank you for the quick answer! When attaching a listener directly on the app's startup, is this sync then reflected in |
Yes. |
@dconeybe Just to confirm: |
Oops, yes. Sorry. That was a typo (I've edited that comment to correct it). You are correct: Note that you can also call |
@dconeybe I'm experiencing a really weird issue when testing offline-syncing. Here is simplified code to see the call order:
This behavior is reproduceable on my end every time I add or remove Maybe I'm missing something here anyway, so it would be great when you could take a look. |
@Nyankoo This definitely does not sound like intended behavior. A few questions:
Thank you. |
You can search for "Repetitions" to see our manual log outputs to see the value change. |
Hi @Nyankoo. I attempted to reproduce the behavior you're noting but did not have success. I observed the expected behavior. Here the test script that I used. Each time I would uncomment exactly one of the "steps" and re-run the app in the Unity Editor.
Each time I observed the expected output, which looked like this:
I'm going to comb through your logs now and see if anything looks suspicious. Can you take a look at my code here to see if it accurately captures what you're trying to do? |
@dconeybe Thank you for the example code! This is the way we're currently testing it on our end. I added the logging part of your code to our app and one thing I noticed was that when I disabled the network, the listener reported |
That's very odd what you're seeing. Unfortunately, I will be out of the office for the next few days so won't get back to investigating until mid-next week. In the meantime, if you can create a minimal app that I can use to reproduce that would be incredibly helpful. Otherwise, we may have to do some debug-based logging. Good luck! I'll touch base next week. |
@dconeybe I tested a bit more and can confirm that your test code works on my end, while even with Firebase 8.0.0, the issue for my Listeners still happens. I tried different Listeners (on a It seems like the "online" and "offline" data are two separate data sets. When online, everything works as normal and the listener grabs the correct cached data ( I noticed this when I saw the following behavior: Step 1
Step 2 (to check that cache works)
Step 3
Step 4 (to check "online" cache)
Another thing I noticed on Android (everything else is currently only tested in the Unity Editor): |
@dconeybe I can also confirm that calling |
I suspect there may be a race condition relating to authentication. From the logs you provided, it appears that some writes to Firestore are done pre-authentication and others are done post-authentication. The writes that are made pre-authentication that are not sync'd to the backend will be paused once authentication succeeds (they will only be resumed if the user subsequently logs out). This would explain why you are seeing the "old value" after enabling the network, because the locally-cached write made while offline and unauthenticated was effectively dropped because the user was not authenticated and now the user is authenticated. I can't confirm this hypothesis yet and I'm still investigating. But I'm wondering if you can test a solution out for me: avoid performing any writes to Firestore until after the user has signed in and authenticated successfully. In other words, ensure that |
@dconeybe All writes via Firestore are made after I authenticated the user, but maybe Firestore tries to sync pending writes before the authentication is finished? Is there maybe a way to test/see this? On that note, is Auth affected by |
I'm not sure what you mean by "maybe Firestore tries to sync pending writes before the authentication is finished". If you never call Calling |
@dconeybe I meant this:
|
Hmm, okay I think I may have reproduced what you are describing. Could you confirm? Here is the code:
Steps to Reproduce:
Expected Results: Actual Results: |
@dconeybe Yes, this also happens when I execute your code on my end! |
Ok. Then it appears that writes made after calling |
I can also confirm that this is not happening on an Android device, so it seems to be (luckily) only an issue affecting the editor. Maybe Unity changed something in their latest editor releases that is causing this? |
I haven't found the root cause yet, but I may have found a workaround. It appears that adding any usage of For example, in the code that I provided in #1083 (comment), adding the line
as the first statement in the Specifically, I changed
to
Can you test out this workaround in your app? Basically, just add a "useless" call to |
@dconeybe Thank you for looking into it! I can confirm that this workaround fixes the issue in your sample, as well as in our app. We called |
Update: I've been able to reproduce this bug in the underlying Firestore C SDK. I'm continuing investigation. If interested, here is the "test app" that I wrote to reproduce: https://gist.github.com/dconeybe/b0d72663ffb744d031cd84eab5194115 |
Update: I've made some progress in the investigation, although I don't have a fix yet. The problem is in the
Basically, when This fix will be to ensure that Firebase Auth's initialization flow executes before trying to run the The good news is that this bug only affects desktop platforms (MacOS, Windows, Linux) but does not affect the mobile platforms (iOS and Android). |
Hmm, there is a bit of a "chicken and egg" problem here. In cl/353905031 (only visible to Googlers) Firestore converted its dependency on Firebase Auth from a "hard" dependency (i.e. directly using However, Firebase Auth does not register its functions with the function registry until it is first used; therefore, if it is never used then the function will never be registered and Firestore will erroneously run in "unauthenticated" mode. So there is an implicit hard requirement that Firestore apps that use Auth explicitly call some Auth method so that its initialization will occur, registering the function in the registry. I'll work with the team on sorting this out. |
The fix for this bug is, unfortunately, not trivial. Since this bug (1) only affects desktop platforms and not mobile platforms and (2) has an easy workaround, I'm going to shelve investigation for now. I'll keep this ticket opened though. TL;DR the workaround is to ensure that there exists some call to |
[REQUIRED] Please fill in the following fields:
[REQUIRED] Please describe the question here:
I stumbled about the following information when looking into Firestore's cache behavior:
When I understand this correctly, data saved to the cache before the app dies/stops is not automatically updated to the Firestore backend when the app launches again.
Is this correct and when yes, what would be the best way to handle the "out of sync" data only present in the cache?
The text was updated successfully, but these errors were encountered: