Skip to content

Promises returned by doc().get() sometimes stop getting resolved if persistence is enabled #3120

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

Closed
optimistiks opened this issue May 27, 2020 · 23 comments

Comments

@optimistiks
Copy link

optimistiks commented May 27, 2020

Describe your environment

  • Operating System version: macOS Catalina 10.15.4 (19E287)
  • Browser version: Safari Version 13.1 (15609.1.20.111.8)
  • Firebase SDK version: 7.14.5
  • Firebase Product: firestore

Describe the problem

In our app, we've discovered that sometimes when you request documents from a collection in quick succession, the documents just stop loading. The promises returned by SDK (doc(id).get()) just stop getting resolved, then callback never fires, and neither does catch.

Steps to reproduce:

It is a very hard to replicate issue.

We've discovered that the issue happens only with enabled persistence. So we've created a codesandbox to reproduce.

https://xqwkf.csb.app

You will see a button. This button loads a document from a collection, using a random id. Normally, when you click it once, you will see 2 logs in the console - START, meaning request is started, and FINISH, meaning promise is resolved, and the document is retrieved.

However, if you click this button fast enough, the promises stop getting resolved. You will only see START logs, and no FINISH logs.

It replicates only sometimes. We couldn't pin point the exact 100% steps to reproduce. So I'm attaching a gist where you see the logs from the console (Firestore debug logs included) from one of the successful attempts. You can search for "POI:" in that gist to find the place when it stopped working. Gist: https://gist.github.com/optimistiks/6176952eff312fba981c0c8d90254639

Relevant Code:

https://codesandbox.io/s/busy-mendel-xqwkf. The code for the above example. Note that it won't work in the codesandbox preview, you need to open it in a separate tab using this link https://xqwkf.csb.app.

@rafikhan
Copy link
Contributor

Hi @optimistiks, thanks for taking the time to compile the logs and code samples together. These were super helpful to understand your situation.

I used the the link you sent me, rapidly clicked the button a few separate times on different machines and browsers and so far I haven't hit the issue you described.

  1. How often are you seeing this happen?
  2. Are users hitting this or is this just during development?
  3. Are you using this in a desktop or mobile browser or an environment like electron?
  4. I noticed your code sample has synchronizedTabs set to true. When you see this do you have different tabs open using Firestore?

@optimistiks
Copy link
Author

Hi @rafikhan ,

Are users hitting this or is this just during development?

We have several reports from our users, but it seems like due to the nature of the issue, some users are completely unaffected. It reproduces during development as well, both when using the full emulator suite, and when connecting to the actual Firebase project.

How often are you seeing this happen?
Are you using this in a desktop or mobile browser or an environment like electron?

We've just run some more tests with my colleague. We were able to reproduce the issue on our staging and production builds in the following browsers:

  • Desktop Safari Version 13.1 (15609.1.20.111.8), macOS 10.15.4 (19E287).
  • iOS 13.4.1 Safari.

We were not able to reproduce it in Chrome. In my first message I said we could, but it was some misunderstanding. Seems like this issue is Safari-only.

I noticed your code sample has synchronizedTabs set to true. When you see this do you have different tabs open using Firestore?

We do have this flag set to true, but we've used a single tab only for debugging. That being said, we were able to reproduce the issue with the flag set to false, as well as with the default cacheSizeBytes. Only when persistence is disabled the issue completely goes away.

@schmidt-sebastian
Copy link
Contributor

@optimistiks Thanks for reporting this and for responding to @rafikhan's questions. I will take a look at this, but will probably not be able to get back to you until Monday or Tuesday.

@schmidt-sebastian
Copy link
Contributor

@optimistiks How often do you need to press the button to reproduce?

I am testing on Desktop Safari 13.1 and everything works for me. We have issues in the past when multiple hundreds of queries are pending. I wonder if this might be the problem you are hitting.

@wallaceturner
Copy link

I am seeing this problem as well. My environment:

  • Operating System version: 13.4.1 mobile
  • Browser version: Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Mobile/15E148 Safari/604.1
  • Firebase SDK version: 7.14.4 (also 7.9.1)

my code is fairly simply -

const ref = database.collection("surveys").doc(survey.id);
const doc = await ref.get();
if(doc.exists)
    ref .update(updates)
else
    await ref.set(survey)    

Eventually the code hangs on the await ref.get() call - no other calls work on the api - that is the entire firebase api is stuck until you refresh - it is fairly easy to recreate - you just need to call code similar to the above 1 to 100 times.

The behaviour seems to only occur when you havee the enablePersistence call on init

firebase.firestore().enablePersistence()

I have not seen this occur when I remove enablePersistence so I suspect they are related.

Can you please advise? I will try and get an easier recreate however you have one above from @optimistiks - are you able to try this on a mobile device? This bug is a bit of huge blocker for me - i have unfortunately had data loss for a client due to not awaiting the result of the save operation. :(

@zemfr
Copy link

zemfr commented Jun 5, 2020

@wallaceturner Do you use onAuthStateChanged before it? I have pretty similar situation if I do it.
Bug is reproduced in Safari on IOS 13.4.1. I thought that problem is related to framework which I use but It is reproduced for example from official documentation.
It is not easy to reproduce. But it is really annoying.

  1. User received the link in a messenger and opens it;
  2. User doesn't wait when onAuthStateChanged is done first time (it can be less than 1 sec) and returns to messenger or just change the tab;
  3. User locks/unlocks iPhone;
  4. User tries open the link again (it opens in new tab) but onAuthStateChanged never resolves. Firestore query also has pending status and never resolves, if I use it after onAuthStateChanged.
    If user closed current tab and returned to previous one, then page works well.

@wallaceturner
Copy link

onAuthStateChanged

@zemfr all my queries are done after onAuthStateChanged - in fact the app isnt rendered until the callback of this method is invoked.

@zemfr
Copy link

zemfr commented Jun 5, 2020

I just tried to reproduce without onAuthStateChanged, only with firestore query and I also get this bug. I use the same scenario that I described. But I noticed that I can't reproduce it, if I remove firebase-auth script from the page
<script src="https://www.gstatic.com/firebasejs/7.14.6/firebase-auth.js"></script>.
Of course I'm not sure 100% that it influences on it but I haven't reproduce this bug without auth script.

@schmidt-sebastian
Copy link
Contributor

@wallaceturner / @zemfr Firebase Auth is also using IndexedDb by default. I wonder if the SDKs are stepping on each other toes here.

@avolkovi Have there been reports that the Auth SDK ends up blocking IndexedDB access?

@wallaceturner
Copy link

@schmidt-sebastian what useful information could i provide? i could give you the stack possibly where it is blocked

@schmidt-sebastian
Copy link
Contributor

@wallaceturner I cannot promise that just looking at the stack will help, but I would love to see it. FWIW, we are currently rewriting the Auth client from scratch. I suspect you can work around this issue in the meantime by disabling IndexedDB access in Firebase Auth. I have to admit that I don't know how to do this though.

@wallaceturner
Copy link

wallaceturner commented Jun 8, 2020

@schmidt-sebastian

work around this issue in the meantime by disabling IndexedDB access in Firebase Auth. I have to admit that I don't know how to do this though.

Thanks, I will give it a shot - you probably have more idea than given I didnt even know it used IndexedDb - any pointers would be appreciated. How do you know its even possible to simply switch storage mechanism ?

@schmidt-sebastian
Copy link
Contributor

I chatted with someone on the Auth team. The current version of the SDK does not allow disabling of IndexedDB. There are also at least two different issues that affect IndexedDB on Safari and Chrome incognito: #1926 and #3004. Both of these issues could explain the behavior that you are seeing.

@schmidt-sebastian
Copy link
Contributor

I am moving this issue over to Firebase Auth to see if there is a chance for a short term mitigation.

@gragland
Copy link

gragland commented Jun 10, 2020

I'm experiencing a similar problem where doc.set() fails to write and never resolves if it's called directly after createUserWithEmailAndPassword but before onAuthStateChanged fires (in that ~200ms or so span of time). If I delay the call to doc.set() by a second so that onAuthStateChanged triggers first then it works fine.

This is problematic when data needs to be written immediately after a user signs up. I've gotten reports from two other users of the React/Firebase template that I sell that they are also seeing this issue.

Thought I'd mention it here since it seems like it could be related. Let me know if I should start a new issue for this.

@3zzy
Copy link

3zzy commented Jun 13, 2020

Happening for me consistently. Using nuxt-firebase.

@nefarioustim
Copy link

I am experiencing exactly the same issue as @gragland in my own project—that follow on doc.set() fails after createUserWithEmailAndPassword and the promises never resolve. I have managed to fix it by downgrading the SDK to 17.4.4, so it is clearly a side-effect of the changes made in 17.5 (potentially the IndexedDB issues as I see those in our Sentry logs from time to time?)

In my case, persistence is not enabled, but we'd like to at some point in the future. I am integrating Firebase with Vue and Vuex, with Firebase generally being called from within Vuex actions.

Also similar to @gragland, I am happy to raise a separate issue or provide more data if needed.

@wallaceturner
Copy link

@nefarioustim @gragland would be good if you start a separate issue

@nefarioustim
Copy link

Done. See #3218 @gragland

@tgangso
Copy link

tgangso commented Jun 16, 2020

Have also experienced this issue for a while, I don't think the issue is new. Implemented a workaround that reloads the app when this happend, but it is not a workable solution. Please prioritize this issue. I was able to reproduce the issue by doing alot of writes on the backend on multiple collections with active listeners in the client. After that sets and gets no longer respond. Primarily an issue with Safari, iOS capacitor app.

@DellaBitta
Copy link
Contributor

Checking in to see if PR 4971 fixed this issue for folks. Thanks!

@google-oss-bot
Copy link
Contributor

Hey @optimistiks. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

@google-oss-bot
Copy link
Contributor

Since there haven't been any recent updates here, I am going to close this issue.

@optimistiks if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.

@firebase firebase locked and limited conversation to collaborators Jul 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests