firebase-android-sdk: Firestore takes up to 90 seconds to get new data after app returns to the foreground
- Android Studio version: 4.1.1
- Firebase Component: Firestore
- Component version: bom 27.1.0
If the app is backgrounded and the phone is idle for a while (say 1-2 hours), then, upon returning to the app, Firestore won’t update with fresh data for up to 90 seconds. Which is a painful user experience because the data is stale and we can’t do anything to force a refresh. My use case is a sports app where the user has to wait with the app open for over a minute to get fresh scores. Another person over in the flutter wrapper sdk was talking about a chat app.
I found a way to reliably reproduce this in a minimal sample project. You’ll find the project and the logcat + steps in this drive folder: https://drive.google.com/drive/folders/1bWPX4IKmQqs86-Khf0CqwwzKOLlqfOEe?usp=sharing
Copying repro steps here:
I wrote a sample app that shows live data from firestore. The data itself is just a timestamp
with the current time (US Central) that's written to firestore by a python script every minute.
So if you look at the app and the time displayed doesn't match the current time, then we know
there's an unreasonable delay.
Repro steps:
1. Disable LTE data, just keep Wifi connected
2. Kill app, open app (around 16:23:35)
3. Wait for app to receive update from network (~16:24:03)
4. Navigate home, open google chrome to put the app in background
5. Force idle (adb shell dumpsys deviceidle force-idle)
6. Keep looking at logcat to see updates every minute (~16:25:02, 16:26:02, 16:27:02, 16:28:02)
7. Wait until there's a connection error that kicks off exponential backoff (~16:28:15 we see a connection error)
8. Open app after 8 minutes (~16:36:10)
- Note: I was just looking at the exp backoff delay retries (it was as high as 84000s, and as soon as I saw 59947 ms I opened the app)
9. Wait with the app open until we finally get a network update at (~16:37:48)
- Note: this is about 1 minute after opening up the app, which matches the last backoff timer :O
10. Revert force-idle (adb shell dumpsys deviceidle unforce)
Expected behavior:
As soon as you re-open app (step 8) it should check the network for new data.
Current behavior:
It is not until after 60ish seconds after re-opening app that we get network data.
Repro attemps: 5/5
See the txt file in drive for more info and some useful logs from Firestore and the sample app
I feel that being backgrounded and the device being idle should not count as a connection error that triggers exponential backoff strategy. Or at least, the sdk should detect that we’ve transitioned from the bg to the foreground and retry immediately instead of waiting for the backoff timer to expire. It’s pretty obvious that this strategy is the issue, I saw backoffs as high as 84000ms, which coincide with reports of delays anywhere from 30-90 seconds…
The only workaround is to either restart the app (awful) or migrate back to real-time database.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 11
- Comments: 20 (6 by maintainers)
This should be included in our next release, which is only a couple of days away.
Very sorry about the delay. I’m wrapping up my current work and will investigate this as my next task. We understand this is a significant issue.
Thank you for the detailed reproduction steps and the test app! I’ll investigate and let you know how it goes. It does look like the issue could be that the exponential backoff doesn’t get reset.
Hello @var-const, may I please check if you were able to investigate? This issue is really a big problem for apps that is constantly listening for data from Firestore.
Practically makes the app unusable if the data cannot be fetched immediately or if the user has to restart the app. I hope you understand the severity of this bug and help to prioritize the fix. Thank you.
I also see the same problem with flutter firestore package. When the app goes background for some time(ex. 5min) and get resumed, any try to access to firestore doesn’t work. Restarting the app is the only choice. It is really critical and ruins all of the user experience in my app 😔. My app can’t stay in production without solving this issue.
Thank you @jorgegil96 for reproducing on Android. Very excited to see that a fix may arrive relatively soon!
I am able to reproduce this occasionally. It seems like the background detection we use errs on the side of caution and is not aggressive enough. It only invokes the restart when it is certain that the app was in the background and transitioned to the foreground. Instead, we want something that always fires when we go back to the foreground. This change will shortly be in review.
Still seeing this in 23.0.1 - it doesn’t look like the backoff retry is reset after entering the foreground (as the CL said it would). Same steps to reproduce still work.
FYI: I noticed it’s significantly harder to get the backoff to trigger in the Android 12 beta, which makes it way harder to get into a state where you can start reproducing this issue. Just thought I’d mention it, in case you all use android 12 in development and are finding it hard to follow the repro steps, maybe try using a previous OS version.
Thanks again for looking into it.
Logs:
Looking forward to seeing this finally solved!