-
Notifications
You must be signed in to change notification settings - Fork 901
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
Firestore: Invalid result returned from getDoc after writing to cache #6739
Comments
The impact of this bug is that we cannot use the recommended approach of inconsistent writes in our application. |
Hi @KoryNunn Thank you so much for filling the support ticket and provide detailed reproduce steps. We have successfully reproduced it and fix is on the way. |
Hi @KoryNunn After discussion, our team believes this is the expected behaviour. The reason for that is with memory persistence, document inside cache gets eagerly garbage collected. So the cache is empty before you call There are two possible fixes for this:
I will close this ticket for now, but please feel free to reopen it if you have any questions. |
This would suggest that in node/web without indexDB either:
Neither of these are obvious or clearly documented, and both are very compromised. Setting cacheSizeBytes also does not mitigate this without indexDB persistance. Previously, it was Firebase's recommendation that writes shouldnt be awaited if they didn't need to be consistently propagated to the server, but this issue means that there are only some scenarios where that will work, and the way in which applications should be implemented with firestore drastically changes based on this consideration. The advertising blurb on the hompage:
Is not true unless the developer treads very carefully and ahs configured and used firebase in a very specific way. To my mind, firestore should not so eagerly garbage collect documents, even in memory mode, when there is plenty of free space in the cache. Additionally, if you remove the |
Hi @KoryNunn , Thank you for the time spend and detailed suggestions. Our team agrees we can optimized the way how memory persistence works. Right now we are trying to prioritize this feature request (b/256897558) among other features. Will keep you posted if we have any news. |
FYI we've hacked around this by doing as you suggested, adding a snapshotListener for every single unique read query, then using getDocFromCache after the snapshot resolves it's first value. This increased our performance by a factor of between 50x and 200x, including writes, which we no longer need to await. I'd recommend looking into implementing a more official way of achieving this as this now lives up to what is described in the advertising blurb. |
Thanks. We will take this into consideration and hopefully we can have better support for this soon. |
@KoryNunn Can you assist us in doing the same? We are using the getDocFromCache, but we are puzzled how to use snapshot listeners with our redux state management. |
Wrap gets and sets in your own functions and within them: First: Create a cacheStatus with a For gets:
For sets:
Use these get and set functions in redux however you want. I will note that this is a bad solution and that firestore should just implement cached gets and sets correctly, which would in turn also mean you don't have to wait for a full round trip for updates. |
As of version 9.21.0 (released April 27, 2023 (release notes)) you can now enable LRU garbage collection when using memory persistence. With LRU garbage collection, the surprising behavior of "eager" garbage collection (mentioned in earlier comment #6739 (comment)) no longer applies. That is, you should see the behavior you expect without having to resort to unnecessarily using a snapshot listener or unnecessarily enabling IndexedDb persistence. Here is example code showing how to create a Firestore instance that uses the new LRU garbage collector for memory persistence: import { FirebaseApp } from 'firebase/app';
import {
Firestore,
initializeFirestore,
memoryLocalCache,
memoryLruGarbageCollector
} from 'firebase/firestore';
function createFirestoreWithMemoryLruGc(app: FirebaseApp): Firestore {
const garbageCollector = memoryLruGarbageCollector();
const localCache = memoryLocalCache({ garbageCollector });
return initializeFirestore(app, { localCache });
} I'm going to close this issue now that there is an official solution; however, feel free to leave new comments or re-open if you feel that the issue has not been adequately resolved. If you find bugs with the new LRU garbage collection please open a new issue. |
[REQUIRED] Describe your environment
[REQUIRED] Describe the problem
After writing a document via
setDoc(ref, data, { merge: true })
, if a write is pending,getDoc
will return only the updated fields from the merge, not including any existing data for that document.Steps to reproduce:
setDoc
and{ merge: true }
, don't await the write.Relevant Code:
The text was updated successfully, but these errors were encountered: