【问题标题】:Use Firebase Phone Authentication with Coroutines将 Firebase 电话身份验证与协程一起使用
【发布时间】:2021-06-14 16:16:51
【问题描述】:

我想使用 Firebase 电话身份验证在我的应用中创建签名活动。身份验证分为三个阶段:

  1. 发送验证码PhoneAuthProvider.verifyPhoneNumber(options)
  2. 验证码PhoneAuthProvider.getCredential(verificationId!!, code)
  3. 使用auth.signInWithCredential(credential) 登录用户

我想使用协程来处理签名过程。我知道如何使用await() 处理代码验证,它包装了auth.signInWithCredential(credential) 返回的Task

我的问题是 PhoneAuthProvider.verifyPhoneNumber(options) 函数,它是 void 函数。我必须使用回调来处理这个方法。

val options = PhoneAuthOptions.newBuilder(auth)
      .setPhoneNumber(phoneNumber)
      .setTimeout(60L, TimeUnit.SECONDS)
      .setCallbacks(callback)
      .build()
PhoneAuthProvider.verifyPhoneNumber(options)

callbacks 在哪里:

callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks(){
            override fun onVerificationCompleted(credential: PhoneAuthCredential) {
                Timber.i("onVerificationCompleted:$credential")
                signInWithPhoneAuthCredential(credential)
            }

            override fun onVerificationFailed(e: FirebaseException) {
                Timber.i(e,"onVerificationFailed")
            }

            override fun onCodeSent(verificationId: String, token: PhoneAuthProvider.ForceResendingToken) {
                Timber.i("onCodeSent:$verificationId")
                storedVerificationId = verificationId
                resendToken = token
            }
        }

问题是:有没有办法将await()verifyPhoneNumber 函数一起使用? 否则,如何使用带有回调的协程来阻塞函数,直到触发回调?

【问题讨论】:

  • callbacks 不是已经在做你想做的事了吗?
  • @NaveenNiraula 但回调不可阻止,我的视图模型必须观察函数的结果
  • 你为什么不把你的代码放在onVerificationCompleted() { } 或者我没有得到你想做的事情?
  • @NaveenNiraula 是的,我可以这样做,但另一个函数 verifyPhoneNumber 将在回调触发之前完成

标签: android firebase kotlin firebase-authentication kotlin-coroutines


【解决方案1】:

您可以使用suspendCoroutine 将 Firebase 回调包装到协程挂起函数中,如下所示:

sealed class PhoneAuthResult {
    data class VerificationCompleted(val credentials: PhoneAuthCredential) : PhoneAuthResult()
    data class CodeSent(val verificationId: String, val token: PhoneAuthProvider.ForceResendingToken)
        : PhoneAuthResult()
}

private suspend fun performPhoneAuth(
    phoneNumber: String,
    firebaseAuth: FirebaseAuth): PhoneAuthResult = 
    suspendCoroutine { cont ->
        val callback = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            override fun onVerificationCompleted(credential: PhoneAuthCredential) {
                Timber.i("onVerificationCompleted:$credential")
                cont.resume(
                    PhoneAuthResult.VerificationCompleted(credential)
                )
            }

            override fun onVerificationFailed(e: FirebaseException) {
                Timber.i(e, "onVerificationFailed")
                cont.resumeWithException(e)
            }

            override fun onCodeSent(verificationId: String, token: PhoneAuthProvider.ForceResendingToken) {
                Timber.i("onCodeSent:$verificationId")
                cont.resume(
                    PhoneAuthResult.CodeSent(verificationId, token)
                )
            }
        }
        
        val options = PhoneAuthOptions.newBuilder(firebaseAuth)
            .setPhoneNumber(phoneNumber)
            .setTimeout(60L, TimeUnit.SECONDS)
            .setCallbacks(callback)
            .build()

        PhoneAuthProvider.verifyPhoneNumber(options)
    }

【讨论】:

    猜你喜欢
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 2020-05-11
    • 2021-07-13
    • 1970-01-01
    相关资源
    最近更新 更多