Controla los errores de la verificación del número de teléfono de Firebase en Android

Cuando falla una llamada a la biblioteca de Firebase PNV, la biblioteca informa un FirebasePhoneNumberVerificationException. En esta página, se enumeran todos los códigos de error que puede contener la excepción, cuándo se produce cada uno y qué debe hacer tu app al respecto.

En esta página, se da por sentado que integraste Firebase PNV como se describe en Comienza a usar Firebase Phone Number Verification en Android.

Cómo se informan los errores

  • Los métodos asíncronos (getVerificationSupportInfo(), getVerifiedPhoneNumber() y los métodos de flujo personalizado) devuelven un Task. Cuando fallan, el Task falla con un FirebasePhoneNumberVerificationException, que recibes en addOnFailureListener.

  • enableTestSession() es síncrono. Arroja un FirebasePhoneNumberVerificationException directamente.

Lee el errorCode de la excepción para averiguar qué salió mal. Los códigos Firebase PNV son constantes en la clase FirebasePnvStatusCodes. Si la falla proviene de los Servicios de Google Play, errorCode también puede ser un valor de CommonStatusCodes, como NETWORK_ERROR.

Un dispositivo o una tarjeta SIM no compatibles no son un error. getVerificationSupportInfo() se ejecuta correctamente y, además, informa isSupported() como false para esa SIM, y getReason() te indica el motivo. Consulta Dispositivos y tarjetas SIM no compatibles.

Códigos de error

Configuración de la sesión de prueba

enableTestSession() arroja estos errores de forma síncrona.

Código de error Causa Acción recomendada
TEST_SESSION_ALREADY_ENABLED
(55508)
Se llamó a enableTestSession() más de una vez en el mismo proceso de la app. FirebasePhoneNumberVerification.getInstance() devuelve la misma instancia cada vez, por lo que esto también sucede cuando se vuelve a crear una Activity que la llama. Llama a enableTestSession() una vez por proceso, por ejemplo, en Application.onCreate(). Consulta Cómo inicializar la biblioteca en el modo de prueba.
INVALID_TEST_NUMBER_ID
(55507)
El token de prueba que se pasó a enableTestSession() está vacío. Asegúrate de que tu compilación pase el token que generaste en Firebase console y solo llama a enableTestSession() cuando el token no esté vacío.

Verificación

Estos errores hacen que falle el objeto Task que devuelve getVerifiedPhoneNumber().

Código de error Causa Acción recomendada
CREDENTIAL_MANAGER_ERROR
(55506)
El Administrador de credenciales de Android no devolvió el número de teléfono. Si el cause de la excepción es un GetCredentialCancellationException, lo más probable es que el usuario haya descartado la pantalla de consentimiento. Ofrece otra forma de verificar el número de teléfono, como SMS. No vuelvas a intentarlo automáticamente, ya que el usuario volvería a ver la pantalla de consentimiento.
CARRIER_NOT_SUPPORTED
(55501)
No se admite el operador de la SIM seleccionada o el dispositivo no tiene la información de suscripción necesaria para verificarlo. Recurre a otro método de verificación, como SMS.
UNSUPPORTED_OPERATION
(55505)
Firebase PNV no está disponible para esta solicitud en el dispositivo. Recurre a otro método de verificación, como SMS.
PREFLIGHT_CHECK_FAILED
(55504)
El backend de Firebase PNV no pudo crear la solicitud de verificación antes de que se mostrara la pantalla de consentimiento. Recurre a otro método de verificación, como SMS. Si esto sucede en cada solicitud, verifica que tu app esté configurada correctamente (consulta Actualiza al modo de producción).
INTEGRITY_CHECK_FAILED
(55503)
El dispositivo o la app no pasaron una verificación de integridad. Recurre a otro método de verificación, como SMS.
INVALID_DIGITAL_CREDENTIAL_RESPONSE
(55502)
No se pudo leer la respuesta del Administrador de credenciales o no se pudo intercambiar por un número de teléfono verificado. Recurrir a otro método de verificación, como SMS
INVALID_TEST_NUMBER_ID
(55507)
En el modo de prueba, el backend de Firebase PNV rechazó el token de prueba, por ejemplo, porque venció. Los tokens de prueba tienen un TTL de 7 días. Un token de prueba rechazado suele informar este código. Si ves otros errores en el modo de prueba, verifica también que el token esté actualizado. Genera un token de prueba nuevo en la consola de Firebase y vuelve a compilar tu app.
ACTIVITY_CONTEXT_REQUIRED
(55509)
El Context que se pasó a getVerifiedPhoneNumber() no es un Activity. El método necesita un Activity para mostrar la pantalla de consentimiento. Pasa el Activity actual. Este es un error en tu app, no una condición que se deba controlar en el tiempo de ejecución.

Verificación de compatibilidad

El Task que muestra getVerificationSupportInfo() falla solo si la verificación en sí no se puede ejecutar. En ese caso, errorCode es un valor CommonStatusCodes de los Servicios de Google Play o CARRIER_NOT_SUPPORTED. Trata el dispositivo como no compatible y recurre a otro método de verificación, como SMS.

Mientras una sesión de prueba está habilitada, getVerificationSupportInfo() no se comunica con el backend de Firebase PNV y siempre informa que la SIM de prueba es compatible, incluso si el token de prueba venció.

Flujo personalizado

Si usas el flujo personalizado en lugar de getVerifiedPhoneNumber(), haz lo siguiente:

  • getDigitalCredentialPayload() falla con PREFLIGHT_CHECK_FAILED o con INVALID_TEST_NUMBER_ID si el backend rechaza tu token de prueba.
  • exchangeCredentialResponseForPhoneNumber() falla con INVALID_DIGITAL_CREDENTIAL_RESPONSE o con INVALID_TEST_NUMBER_ID si el backend rechaza tu token de prueba.
  • Tu propia llamada al Administrador de credenciales arroja un GetCredentialException, que controlas directamente.

Dispositivos y tarjetas SIM no compatibles

Cuando isSupported() es false para una SIM, getReason() devuelve uno de los siguientes valores de VerificationSupportStatus:

Valor Significado
INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED No se admite el operador de la SIM. Consulta Operadores admitidos.
INCAPABLE_DUE_TO_ANDROID_VERSION El dispositivo ejecuta una versión de Android anterior a Android 9 (nivel de API 28).
INCAPABLE_DUE_TO_SIM_STATE La SIM no está lista. Una SIM que está bloqueada o que aún se está cargando también puede informar INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED, ya que primero se verifica el operador.

En cada caso, usa otro método de verificación, como SMS, para esa SIM.

Ejemplo

En el siguiente ejemplo, se controlan los errores que una app típica debe distinguir cuando llama a 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()
        }
    }
}

En este ejemplo, showSmsVerification() es el flujo de verificación del número de teléfono existente de tu app.

Próximos pasos