带有firebase函数的Kotlin协程序

2wnc66cl  于 2022-12-13  发布在  Kotlin
关注(0)|答案(2)|浏览(101)

我在用Kotlin协同程序实现Firebase匿名登录功能时遇到了问题。
下面是代码:
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")
   }
}

当Android设备连接到互联网时,它工作正常。
但是当我在没有互联网的情况下测试这段代码时,它永远不会完成,也就是说,执行永远不会到达FirebaseHelper.ktif else块。
我找不到任何资源来帮助我了解这个问题的原因和任何可能的解决方案。
在解决方案方面,我能想到的一个想法是在一段时间后强制取消await()函数的执行,但我找不到与实现相关的任何内容。

r6hnlfcb

r6hnlfcb1#

当Android设备连接到互联网时,它工作正常。
由于身份验证操作需要Internet连接,因此这是预期的行为。
但是当我在没有互联网的情况下测试这个代码时,它永远不会完成。
如果没有互联网,你就无法访问Firebase服务器,因此才会出现这种情况。但是,根据await()函数的官方文档:
这个挂起的函数是可取消的。如果当前协程的作业在这个挂起的函数等待时被取消或完成,这个函数立即恢复并返回CancellationException。
或者,您可以在执行身份验证之前简单地检查用户是否连接到互联网。

j13ufse2

j13ufse22#

我是通过try catch块和FirebaseHelper.kt文件中的withTimeout()函数来实现的,下面是解决方案的代码:

fun getUserID() = flow {
        try {
            val signInTask = Firebase.auth.signInAnonymously()
            kotlinx.coroutines.withTimeout(5000) {
                signInTask.await()
            }
            if (signInTask.isSuccessful){
                emit("Successful")
            } else {
                emit("Failed")
            }
        } catch (e: Exception){
            emit("Can't connect to the server\nPlease check your internet connection and retry")
        }
    }

withTimeout(timeMillis: Long, block: suspend CoroutineScope.() -> T)运行给定的suspend block,持续timeMillis毫秒,如果超时,则抛出TimeoutCancellationException

相关问题