将 Firebase Phone 身份验证与协程一起使用
Use Firebase Phone Authentication with Coroutines
我想在我的应用程序中使用 Firebase phone 身份验证创建签名 activity。身份验证分为三个阶段:
- 正在发送验证码
PhoneAuthProvider.verifyPhoneNumber(options)
- 验证代码
PhoneAuthProvider.getCredential(verificationId!!, code)
- 使用
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
函数一起使用?
否则,我如何使用带有回调的协程来阻止函数直到回调被触发?
您可以使用 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)
}
我想在我的应用程序中使用 Firebase phone 身份验证创建签名 activity。身份验证分为三个阶段:
- 正在发送验证码
PhoneAuthProvider.verifyPhoneNumber(options)
- 验证代码
PhoneAuthProvider.getCredential(verificationId!!, code)
- 使用
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
函数一起使用?
否则,我如何使用带有回调的协程来阻止函数直到回调被触发?
您可以使用 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)
}