I'm trying to request data from firestore in a background thread with setting the source to Source.Server, with the help of Play services Task API as the following:
suspend fun getUsers() = withContext(IO) { try { val ref = Firebase.firestore.collection("users") val task = ref.get(Source.SERVER) val snapshot = Tasks.await(task) val users = snapshot.map { it.toObject(User::class.java) } } catch (e: Exception) { if (e is FirebaseFirestoreException) { Log.i(TAG, "FirebaseFirestoreException: ${e.localizedMessage}") } else if (e is ExecutionException){ //the mentioned error satisfy this if clause, not the first one Log.i(TAG, "ExecutionException: ${e.localizedMessage}") }else{ Log.i(TAG, "Not a FirebaseFirestoreException nor an Excecution Exception: ${e.localizedMessage}") } } } Sometimes the above code gives me this error:
2020-09-29 18:03:51.814 19502-19502/com.first.academy I/Fuck: ExecutionException: com.google.firebase.firestore.FirebaseFirestoreException: Failed to get documents from server. (However, these documents may exist in the local cache. Run again without setting source to SERVER to retrieve the cached documents.)
And app crashes with this error when I run the code whithout try catch block:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.first.academy, PID: 24934 java.util.concurrent.ExecutionException: com.google.firebase.firestore.FirebaseFirestoreException: Failed to get documents from server. (However, these documents may exist in the local cache. Run again without setting source to SERVER to retrieve the cached documents.) at com.google.android.gms.tasks.Tasks.zzb(Unknown Source) at com.google.android.gms.tasks.Tasks.await(Unknown Source) at com.first.academy.main.MainViewModel$getUsers$2.invokeSuspend(MainViewModel.kt:88) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665) Caused by: com.google.firebase.firestore.FirebaseFirestoreException: Failed to get documents from server. (However, these documents may exist in the local cache. Run again without setting source to SERVER to retrieve the cached documents.) at com.google.firebase.firestore.Query.lambda$getViaSnapshotListener$1(Query.java:995) at com.google.firebase.firestore.Query$$Lambda$2.onEvent(Query.java) at com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$2(Query.java:1142) at com.google.firebase.firestore.Query$$Lambda$3.onEvent(Query.java) at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0(AsyncEventListener.java:42) at com.google.firebase.firestore.core.AsyncEventListener$$Lambda$1.run(AsyncEventListener.java) at com.google.firebase.firestore.util.Executors$$Lambda$1.execute(Executors.java) at com.google.firebase.firestore.core.AsyncEventListener.onEvent(AsyncEventListener.java:39) at com.google.firebase.firestore.core.QueryListener.raiseInitialEvent(QueryListener.java:176) at com.google.firebase.firestore.core.QueryListener.onOnlineStateChanged(QueryListener.java:116) at com.google.firebase.firestore.core.EventManager.handleOnlineStateChange(EventManager.java:178) at com.google.firebase.firestore.core.SyncEngine.handleOnlineStateChange(SyncEngine.java:361) at com.google.firebase.firestore.core.MemoryComponentProvider$RemoteStoreCallback.handleOnlineStateChange(MemoryComponentProvider.java:114) at com.google.firebase.firestore.remote.RemoteStore$$Lambda$1.handleOnlineStateChange(RemoteStore.java) at com.google.firebase.firestore.remote.OnlineStateTracker.setAndBroadcastState(OnlineStateTracker.java:176) at com.google.firebase.firestore.remote.OnlineStateTracker.handleWatchStreamFailure(OnlineStateTracker.java:149) at com.google.firebase.firestore.remote.RemoteStore.handleWatchStreamClose(RemoteStore.java:481) at com.google.firebase.firestore.remote.RemoteStore.access$200(RemoteStore.java:53) at com.google.firebase.firestore.remote.RemoteStore$1.onClose(RemoteStore.java:181) at com.google.firebase.firestore.remote.AbstractStream.close(AbstractStream.java:344) at com.google.firebase.firestore.remote.AbstractStream.handleServerClose(AbstractStream.java:398) at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.lambda$onClose$3(AbstractStream.java:151) at com.google.firebase.firestore.remote.AbstractStream$StreamObserver$$Lambda$4.run(AbstractStream.java) at com.google.firebase.firestore.remote.AbstractStream$CloseGuardedRunner.run(AbstractStream.java:67) at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.onClose(AbstractStream.java:137) at com.google.firebase.firestore.remote.FirestoreChannel$1.onClose(FirestoreChannel.java:135) at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426) at io.grpc.internal.ClientCallImpl.access$500(ClientCallImpl.java:66) E/AndroidRuntime: at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:689) at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$900(ClientCallImpl.java:577) at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:751) at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:740) at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$DelayedStartFactory.run(AsyncQueue.java:229) at java.lang.Thread.run(Thread.java:776)
The exception thrown when this error happens is not a FirebaseFirestoreException, and doesn't satisfy the first if clause, even though the error is related to firestore as the message says, rather it's an ExecutionException.
How to handle this particular error to show different message to the user? How to know if the reason is this specific error when an exception is thrown because the ExcecutionException could be thrown for different reasons?
e is ExecutionException. Nowhere in that message does it say "ExcecutionException".