connectUser() flushes the offline cache on a plain connectivity failure (offlineEnabled=true)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 50/100
Direzione di ricerca
Inizia da ChatClient.setUser() e segui il relativo gestore onErrorSuspend fino a disconnectSuspend(flushPersistence = true), disconnectUserSuspend(), repositoryFacade.clear() e mutableClientState.clearState(). Riproduci l’avvio a freddo offline con offlineEnabled=true e verifica che un errore di connectUser() dovuto esclusivamente alla connettività preservi i dati memorizzati nella cache e lo stato dell’utente locale; aggiungi la copertura di regressione se è possibile identificare la posizione del test pertinente.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Describe the bug
A failed connectUser() (e.g. device is offline) triggers ChatClient.setUser()'s internal .onErrorSuspend { disconnectSuspend(flushPersistence = true) } handler, which wipes the client's offline Room cache via disconnectUserSuspend(flushPersistence = true) -> repositoryFacade.clear() and resets mutableClientState.clearState(). This happens on every failed connectUser() call, including a plain connectivity failure — not just auth errors — so a cold app launch while offline destroys the exact offline cache that ChatClientConfig(offlineEnabled = true) is meant to preserve for a returning, previously-authenticated user.
This directly contradicts the Offline Support guide, which frames flushPersistence = true as something a caller explicitly opts into (e.g. on logout), not a side effect of a failed reconnect — and the Handling User Connection guide, which explicitly says: "Make sure your implementation handles a missing network without recording it as a fatal error" — implying a connectUser() failure due to missing network is an expected, non-fatal occurrence, yet its side effect (wiping the offline cache) isn't documented anywhere.
SDK version
- 7.6.0 and 7.7.0 (confirmed on both by reading the actual
stream-chat-android-clientsources for each version; 7.7.0's changelog doesn't mention a related fix, and re-testing on-device against 7.7.0 reproduces the same behavior)
To Reproduce
- Sign in successfully with
ChatClient.Builder(apiKey, context).config(ChatClientConfig(offlineEnabled = true)).build(),connectUser(...), and browse channels while online so the offline cache is populated. - Fully close the app (kill the process).
- Put the device in airplane mode / disconnect all networks.
- Cold-launch the app again and call
connectUser(...)for the same user with notimeoutMilliseconds(or any value) — it resolves asResult.Failuresince the socket can't connect. - Observe:
ChannelsScreen/ChannelListViewModelfor this client now has an empty/perpetually-loading channel list,getCurrentUser()returnsnull, and the client's offline database has been cleared — even though step 1 successfully cached channels for this exact user.
Traced root cause (in io.getstream.chat.android.client.ChatClient, 7.6.0/7.7.0 sources):
private suspend fun setUser(...): Result<ConnectionData> {
...
return when {
...
userState is UserState.NotSet -> {
mutableClientState.setUser(user)
initializeClientWithUser(user, cacheableTokenProvider, isAnonymous)
userStateService.onSetUser(user, isAnonymous)
chatSocket.connectUser(user, isAnonymous)
mutableClientState.setInitializationState(InitializationState.COMPLETE)
waitFirstConnection(timeoutMilliseconds) // <- resolves Result.Failure offline, no timeout given
}
...
}.onErrorSuspend {
disconnectSuspend(flushPersistence = true) // <- runs on ANY Result.Failure, including pure connectivity failure
}
}
private suspend fun disconnectUserSuspend(flushPersistence: Boolean) {
...
if (flushPersistence) {
repositoryFacade.clear() // wipes the offline Room cache
userCredentialStorage.clear()
}
...
mutableClientState.clearState() // getCurrentUser() becomes null again
...
}
Expected behavior
A connectUser() failure caused purely by lack of connectivity should not flush the offline persistence layer or clear the client's local user state — the whole point of offlineEnabled = true is that a previously-authenticated user can browse cached channels/messages without a live connection. At minimum, this destructive side effect should be documented, or ideally scoped to real auth/credential errors rather than every Result.Failure (including plain network-unreachable cases).
Workaround we're using in the meantime
Checking device connectivity (our own ConnectivityManager-backed monitor) before calling connectUser() at all, and skipping the call entirely when known-offline — this avoids triggering the destructive path, at the cost of not restoring the previously-connected user's session (and thus not showing cached channels) on that specific cold-offline launch.
Additional context
- Related: #6009 ("Switching user cause ChannelScreen goes in an infinite loop and no chats are shown") describes the same downstream symptom (
ChannelsScreenstuck/empty after adisconnect(flushPersistence = true)), triggered by an explicitswitchUser()call rather than an implicit connectivity failure — but the underlying "post-flush, channel list never recovers" behavior looks like the same class of issue. - Happy to provide a minimal repro project if useful.
- Lingua principale
- Kotlin
- Stelle
- 1.7k
- Fork
- 320
- Merge medio
- 1g 9h
- PR unite (30g)
- 134
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di GetStream/stream-chat-android
-
feature request
Difficoltà 3/5 1-2 giorni Idoneità per principianti 65/100
GetStream/stream-chat-android#6556 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Add Sort Order Support for Media and Files Attachments Lists in Channel InfoForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Apertafeature request
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
GetStream/stream-chat-android#6359 ·
I maintainer di solito rispondono entro 1 giorno
-
feature request
Difficoltà 3/5 1-2 giorni Idoneità per principianti 38/100
GetStream/stream-chat-android#6243 ·
I maintainer di solito rispondono entro 1 giorno
-
Unable to wrap ChannelList height due to internal LazyColumn .fillMaxSize()Forse già presa @Ahmetkaragunlu l’ha presa 5 giorni fa. Apertacompose feature request
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
GetStream/stream-chat-android#5612 · 4 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Should Support Larger fileApertacore feature request
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
GetStream/stream-chat-android#5279 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di GetStream/stream-chat-android
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
lysine-dev/okhttp#9814 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
getdictus/dictus-android#187 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 79/100
bryangerlach/rdgen#319 ·
-
Opening a shared location shows your current location instead of the location that was sharedApertaT-Defect
Difficoltà 2/5 1-3 ore Idoneità per principianti 60/100
element-hq/element-x-android#7999 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno