I was having a problem implementing the Firebase anonymous sign-in function with Kotlin coroutine.
Following is the code for that:
Repository.kt
suspend fun getUserId(){
firebaseHelper.getUserId().collect{
if (it == "Successful"){
emit(it)
} else {
emit("Task unsuccessful")
}
}
}
FirebaseHelper.kt
fun getUserId() = flow {
val firebaseLoginAsync = Firebase.auth.signInAnonymously().await()
if (firebaseLoginAsync.user != null && !firebaseLoginAsync.user?.uid.isNullOrEmpty()) {
emit("Successful")
} else {
emit("Failed")
}
}
It works fine when the android device is connected to the internet.
But when I test this code without the internet it never completes, that is, the execution never reaches the if else
block of FirebaseHelper.kt
.
I was unable to find any resource that would help me understand the cause of this problem and any possible solution.
One idea that I can think of on the solution side is to forcefully cancel the await()
functions execution after some time but I can’t find anything related to implementation.
2
Answers
The way that I made it work is with help of
try catch
block andwithTimeout()
function inFirebaseHelper.kt
file. Following is the code of solution:withTimeout(timeMillis: Long, block: suspend CoroutineScope.() -> T)
runs the given suspendblock
fortimeMillis
milliseconds and throwsTimeoutCancellationException
if the timeout was exceeded.Since an authentication operation requires an internet connection, then that’s the expected behavior.
Without the internet, there is no way you can reach Firebase servers, hence that behavior. However, according to the official documentation of await() function:
Or you can simply check if the user is connected to the internet before performing the authentication.