Open ishowta opened 2 years ago
Thanks for providing this test case. The test mostly passes for me but let's look at one of the failed runs. Note that the test only fails with persistence disabled. If persistence is enabled, the test always passes as the document is always in the cache.
Logs are here: https://gist.github.com/schmidt-sebastian/6979dc61b8acf35b020aa045856cfb1a
getDoc
is issued, but nothing happens yet.updateDoc
is sent to the backend. The backend does not yet sent a response.getDoc
is sent to the backend.getDoc
at time 1. Note that this is according to our specification as the read for the document occurred before the update was written (update at nanos: 969724000
versus read at nanos: 954131000
)getDoc
then runs. We are now in the short window were we have the result of the first getDoc
call in the cache and so we return it. If the first getDoc
had already returned its result to your code, the document would no longer be in the cache and we would issue another backend call and you would see the updated data.Since memory persistence does not store any information when there are no active listeners, there is likely not a realistic way for us to prevent this scenario. This problem will not exist with memory persistence or if you keep your listeners active. I will discuss with my team if we should treat this case specifically.
Thank you for this exercise!
Thank you for your detailed investigation!
By the way, I didn't include it because it's hard to reproduce, but what I actually encountered was a problem via the functions call like below.
I don't understand about the behavior of memory persistence yet, but in this case, I have a feeling that memory persistence won't work since doc is being changed externally.
(I'm using a deepl translator for most of the text, so it may be hard to read. I'm sorry.)
// 1. async get (Somewhere.)
void getDoc(docRef);
// 2. sync function call
await functions.httpsCallable('updateData')();
// 3. get (I'm actually opening another page after calling the function and getting the doc there.)
const dataGotAfterUpdate = await getDoc(docRef);
[REQUIRED] Describe your environment
[REQUIRED] Describe the problem
When I call DocumentReference.get() asynchronously, update the document synchronously, and then do DocumentReference.get() again, I expect to get the last updated document, however, sometimes the old data may be retrieved. (See the code below.)
DocumentReference.get() looks like it's internally treating the request as a query and passing it to the EventManager, but EventManagerImpl manages the same query in one place, so this probably causes the new request to be lumped in with the old one.
https://github.com/firebase/firebase-js-sdk/blob/4bd3a888353c26854142b1861f12e0222151af96/packages/firestore/src/core/event_manager.ts#L64
Steps to reproduce:
The code below (Occasional failures)
Relevant Code: