如何正确处理 FirebaseAuth 异步结果?

Raf*_* V. 2 android async-await firebase-authentication kotlin-coroutines

在我的 Android 应用程序上,我尝试使用 FirebaseAuth 实现简单的登录/注册。我想使用 Kotlin 协程来正确处理来自 Firebase 的响应。所以我将其添加到我的 gradle 文件中:

"org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$kotlin_play_services_version"
Run Code Online (Sandbox Code Playgroud)

之后,我可以.await()在 FirebaseAuth 请求后进行调用。这是负责处理登录的代码:

override suspend fun signIn(email: String, password: String): JobResult<User> {

    var errorMessage = ""
    var user: User? = null

    firebaseAuth.signInWithEmailAndPassword(email, password)
        .addOnSuccessListener { result ->
            user = UserMapper().mapFromFirebaseUser(result.user)
        }
        .addOnFailureListener { result ->
            errorMessage = result.message ?: CONSTANTS.BAD_REQUEST
            user = null
        }.await()

    user?.run {
        return JobResult.Success(this)
    }
    return JobResult.Fail(errorMessage, HttpURLConnection.HTTP_BAD_REQUEST)

}
Run Code Online (Sandbox Code Playgroud)

所以基本上发生的事情是我调用 Firebase 的 Sign In 方法传递正确的参数,并添加成功和失败侦听器。根据结果​​,变量user可能包含用户的信息或为空。根据该变量,我将成功或失败结果返回到请求它的代码部分。

如果结果为正(成功侦听器),则一切正常,但是,如果结果不是成功结果,则.await()永远不会执行调用后的代码!仿佛在等待一个成功的结果,并且会永远等待。这意味着如果请求由于某种原因失败,该挂起函数将永远不会返回任何结果,它只是等待。

我希望收到任何结果后立即运行其余代码。我该怎么做?我在这里遗漏了一些明显的东西吗?是否有任何方法可以“突破”这一点await(),并在到达故障侦听器后继续执行其余代码?

谢谢你!

Dou*_*son 7

你应该这样写。如果您要使用协程,则无需将回调侦听器附加到任务。只需await()任务并使用try/catch来处理结果:

try {
    val result = firebaseAuth.signInWithEmailAndPassword(email, password).await()
    val user = UserMapper().mapFromFirebaseUser(result.user)
    // continue using user here...
}
catch (e: Exception) {
    // deal with the error properly
}
Run Code Online (Sandbox Code Playgroud)