如果对 Firebase PNV 库的调用失败,该库会报告 FirebasePhoneNumberVerificationException。本页面列出了该异常可能携带的所有错误代码、每个错误代码的发生时间以及应用应采取的措施。
本页假设您已按照在 Android 上开始使用 Firebase Phone Number Verification 中的说明集成了 Firebase PNV。
错误的报告方式
异步方法(
getVerificationSupportInfo()、getVerifiedPhoneNumber()和自定义流程方法)会返回Task。如果这些操作失败,Task将失败并显示FirebasePhoneNumberVerificationException,您会在addOnFailureListener中收到该错误。enableTestSession()是同步的。它会直接抛出FirebasePhoneNumberVerificationException。
阅读异常的 errorCode,了解出了什么问题。Firebase PNV 代码是 FirebasePnvStatusCodes 类中的常量。如果失败是由 Google Play 服务引起的,errorCode 也可以是 CommonStatusCodes 值,例如 NETWORK_ERROR。
设备或 SIM 卡不受支持不属于错误。getVerificationSupportInfo() 成功,并针对该 SIM 卡将 isSupported() 报告为 false,而 getReason() 会告诉您原因。请参阅不支持的设备和 SIM 卡。
错误代码
测试会话设置
这些错误由 enableTestSession() 同步抛出。
| 错误代码 | 原因 | 建议采取的操作 |
|---|---|---|
TEST_SESSION_ALREADY_ENABLED(55508) |
在同一应用进程中多次调用了 enableTestSession()。FirebasePhoneNumberVerification.getInstance() 每次都会返回同一实例,因此当调用它的 Activity 重新创建时,也会发生这种情况。 |
每个进程调用一次 enableTestSession(),例如在 Application.onCreate() 中。请参阅在测试模式下初始化库。 |
INVALID_TEST_NUMBER_ID(55507) |
传递给 enableTestSession() 的测试令牌为空。 |
确保您的 build 传递您在 Firebase 控制台中生成的令牌,并且仅在令牌不为空时调用 enableTestSession()。 |
验证
这些错误会导致 getVerifiedPhoneNumber() 返回的 Task 失败。
| 错误代码 | 原因 | 建议采取的操作 |
|---|---|---|
CREDENTIAL_MANAGER_ERROR(55506) |
Android Credential Manager 未返回电话号码。如果异常的 cause 为 GetCredentialCancellationException,则用户很可能关闭了权限请求页面。 |
提供其他电话号码验证方式,例如短信。请勿自动重试,因为用户会再次看到权限请求页面。 |
CARRIER_NOT_SUPPORTED(55501) |
所选 SIM 卡的运营商不受支持,或者设备没有验证该 SIM 卡所需的订阅信息。 | 回退到其他验证方法,例如短信。 |
UNSUPPORTED_OPERATION(55505) |
Firebase PNV 无法在设备上处理此请求。 | 回退到其他验证方法,例如短信。 |
PREFLIGHT_CHECK_FAILED(55504) |
在显示权限请求页面之前,Firebase PNV 后端无法创建验证请求。 | 改用其他验证方法,例如短信。如果每个请求都会发生这种情况,请检查您的应用是否设置正确(请参阅升级到生产模式)。 |
INTEGRITY_CHECK_FAILED(55503) |
设备或应用未通过完整性检查。 | 回退到其他验证方法,例如短信。 |
INVALID_DIGITAL_CREDENTIAL_RESPONSE(55502) |
无法读取来自 Credential Manager 的响应,或无法将其交换为已验证的电话号码。 | 回退到其他验证方法,例如短信。 |
INVALID_TEST_NUMBER_ID(55507) |
在测试模式下,Firebase PNV 后端拒绝了测试令牌,例如因为令牌已过期。测试令牌的 TTL 为 7 天。被拒绝的测试令牌通常会报告此代码;如果您在测试模式下看到其他错误,请检查您的令牌是否为最新。 | 在 Firebase 控制台中生成新的测试令牌,然后重新构建应用。 |
ACTIVITY_CONTEXT_REQUIRED(55509) |
传递给 getVerifiedPhoneNumber() 的 Context 不是 Activity。该方法需要 Activity 才能显示权限请求页面。 |
传递当前 Activity。这是应用中的 bug,而不是要在运行时处理的条件。 |
支持检查
只有在检查本身无法运行时,getVerificationSupportInfo() 返回的 Task 才会失败。在这种情况下,errorCode 是 Google Play 服务 CommonStatusCodes 值或 CARRIER_NOT_SUPPORTED。将设备视为不受支持,并回退到其他验证方法(例如短信)。
启用测试会话后,getVerificationSupportInfo() 不会与 Firebase PNV 后端联系,并且始终会将测试 SIM 卡报告为受支持,即使测试令牌已过期也是如此。
自定义流程
如果您使用自定义流程而不是 getVerifiedPhoneNumber():
getDigitalCredentialPayload()失败,并显示PREFLIGHT_CHECK_FAILED;如果后端拒绝您的测试令牌,则显示INVALID_TEST_NUMBER_ID。exchangeCredentialResponseForPhoneNumber()失败并显示INVALID_DIGITAL_CREDENTIAL_RESPONSE,或者如果后端拒绝您的测试令牌,则失败并显示INVALID_TEST_NUMBER_ID。- 您自己对 Credential Manager 的调用会抛出
GetCredentialException,您需要直接处理该异常。
不支持的设备和 SIM 卡
如果 SIM 卡的 isSupported() 为 false,getReason() 会返回以下 VerificationSupportStatus 值之一:
| 值 | 含义 |
|---|---|
INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED |
不支持 SIM 卡的运营商。请参阅支持的运营商。 |
INCAPABLE_DUE_TO_ANDROID_VERSION |
设备搭载的 Android 版本低于 Android 9(API 级别 28)。 |
INCAPABLE_DUE_TO_SIM_STATE |
SIM 卡尚未准备就绪。已锁定或仍在加载的 SIM 卡也可能会报告 INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED,因为系统会先检查运营商。 |
在每种情况下,请针对该 SIM 卡使用其他验证方法,例如短信。
示例
以下示例处理了典型应用在调用 getVerifiedPhoneNumber() 时需要区分的错误:
Kotlin
import android.util.Log
// Credential Manager is included with the Firebase PNV library.
import androidx.credentials.exceptions.GetCredentialCancellationException
import com.google.firebase.pnv.FirebasePhoneNumberVerification
import com.google.firebase.pnv.FirebasePhoneNumberVerificationException
import com.google.firebase.pnv.FirebasePnvStatusCodes
private const val TAG = "PhoneVerification"
// In your Activity:
private fun verifyPhoneNumber() {
FirebasePhoneNumberVerification.getInstance()
.getVerifiedPhoneNumber(this)
.addOnSuccessListener { result ->
// Send result.getToken() to your backend.
}
.addOnFailureListener { e -> handleFpnvError(e) }
}
private fun handleFpnvError(e: Exception) {
if (e !is FirebasePhoneNumberVerificationException) {
Log.w(TAG, "Firebase PNV failed", e)
showSmsVerification()
return
}
when (e.errorCode) {
FirebasePnvStatusCodes.CREDENTIAL_MANAGER_ERROR -> {
if (e.cause is GetCredentialCancellationException) {
// The user dismissed the consent screen.
}
showSmsVerification()
}
FirebasePnvStatusCodes.INVALID_TEST_NUMBER_ID -> {
// Test mode only: generate a new test token.
Log.e(TAG, "Firebase PNV test token rejected", e)
}
FirebasePnvStatusCodes.ACTIVITY_CONTEXT_REQUIRED -> {
// App bug: pass an Activity to getVerifiedPhoneNumber().
Log.e(TAG, "Firebase PNV needs an Activity context", e)
}
else -> {
// Carrier not supported, network errors, and other failures.
Log.w(TAG, "Firebase PNV failed with error code ${e.errorCode}", e)
showSmsVerification()
}
}
}
在此示例中,showSmsVerification() 是应用的现有电话号码验证流程。
后续步骤
- 如需详细了解每个类和常量,请参阅 Firebase PNV API 参考文档。
- 如需在服务器上验证令牌,请参阅验证 Firebase PNV 令牌。