Как обрабатывать ошибки подтверждения номера телефона в Firebase на Android

Если вызов библиотеки Firebase PNV не удался, библиотека сообщает об ошибке FirebasePhoneNumberVerificationException. На этой странице перечислены все коды ошибок, которые может содержать исключение, когда они возникают и что ваше приложение должно с ними делать.

Предполагается, что вы уже интегрировали Firebase PNV, как описано в статье Начало работы с Firebase Phone Number Verification на Android.

Как сообщается об ошибках

  • Асинхронные методы (getVerificationSupportInfo(), getVerifiedPhoneNumber() и методы специального процесса) возвращают Task. Если они не выполняются, то Task возвращает ошибку FirebasePhoneNumberVerificationException, которая передается в addOnFailureListener.

  • enableTestSession() – синхронный метод. Она бросает FirebasePhoneNumberVerificationException прямо в цель.

Прочитайте errorCode исключения, чтобы узнать, что пошло не так. Коды Firebase PNV – это константы в классе FirebasePnvStatusCodes. Если сбой произошел в сервисах Google Play, errorCode также может быть значением CommonStatusCodes, например NETWORK_ERROR.

Неподдерживаемое устройство или SIM-карта не считаются ошибкой. getVerificationSupportInfo() выполняется успешно и сообщает isSupported() как false для этой SIM-карты, а getReason() сообщает причину. Подробнее о неподдерживаемых устройствах и SIM-картах…

Коды ошибок

Настройка тестового сеанса

Эти ошибки синхронно генерируются методом enableTestSession().

Код ошибки Причина Рекомендуемое действие
TEST_SESSION_ALREADY_ENABLED
(55508)
Метод enableTestSession() был вызван более одного раза в одном и том же процессе приложения. FirebasePhoneNumberVerification.getInstance() возвращает один и тот же экземпляр, поэтому это также происходит, когда вызывающий его Activity создается заново. Вызывайте enableTestSession() один раз для каждого процесса, например в Application.onCreate(). Подробнее о том, как инициализировать библиотеку в тестовом режиме…
INVALID_TEST_NUMBER_ID
(55507)
Тестовый токен, переданный в enableTestSession(), пуст. Убедитесь, что сборка передает токен, созданный в консоли Firebase, и вызывайте enableTestSession(), только если токен не пустой.

Проверка

Эти ошибки приводят к сбою Task, возвращаемого getVerifiedPhoneNumber().

Код ошибки Причина Рекомендуемое действие
CREDENTIAL_MANAGER_ERROR
(55506)
Менеджер учетных данных Android не вернул номер телефона. Если cause исключения – GetCredentialCancellationException, скорее всего, пользователь закрыл окно запроса доступа. Предложите другой способ подтверждения номера телефона, например SMS. Не повторяйте попытку автоматически, иначе пользователь снова увидит окно запроса доступа.
CARRIER_NOT_SUPPORTED
(55501)
Оператор выбранной SIM-карты не поддерживается или на устройстве нет информации о подписке, необходимой для проверки. Используйте другой способ подтверждения, например SMS.
UNSUPPORTED_OPERATION
(55505)
Firebase PNV недоступен для этого запроса на устройстве. Используйте другой способ подтверждения, например SMS.
PREFLIGHT_CHECK_FAILED
(55504)
Серверная часть Firebase PNV не смогла создать запрос на подтверждение до того, как было показано окно запроса доступа. Используйте другой способ подтверждения, например SMS. Если это происходит при каждом запросе, проверьте, правильно ли настроено приложение (см. раздел Переход в производственный режим).
INTEGRITY_CHECK_FAILED
(55503)
Устройство или приложение не прошло проверку целостности. Используйте другой способ подтверждения, например SMS.
INVALID_DIGITAL_CREDENTIAL_RESPONSE
(55502)
Не удалось прочитать ответ от Менеджера учетных данных или обменять его на подтвержденный номер телефона. Используйте другой способ подтверждения, например SMS.
INVALID_TEST_NUMBER_ID
(55507)
В тестовом режиме серверная часть Firebase PNV отклонила тестовый токен, например из-за истечения срока действия. Для тестовых токенов TTL составляет семь дней. Если вы видите другие ошибки в тестовом режиме, проверьте, актуален ли ваш токен. Сгенерируйте новый тестовый токен в консоли Firebase и пересоберите приложение.
ACTIVITY_CONTEXT_REQUIRED
(55509)
Объект Context, переданный в getVerifiedPhoneNumber(), не является объектом Activity. Для показа окна запроса доступа методу требуется Activity. Передайте текущий Activity. Это ошибка в приложении, а не условие, которое нужно обрабатывать во время выполнения.

Проверка поддержки

Объект Task, возвращаемый методом getVerificationSupportInfo(), не будет получен, только если не удастся выполнить саму проверку. В этом случае errorCode – это значение CommonStatusCodes сервисов Google Play или CARRIER_NOT_SUPPORTED. Считайте устройство неподдерживаемым и используйте другой способ подтверждения, например SMS.

Пока тестовый сеанс активен, getVerificationSupportInfo() не связывается с сервером Firebase PNV и всегда сообщает, что тестовая SIM-карта поддерживается, даже если срок действия тестового токена истек.

Собственный поток

Если вы используете специальный процесс вместо getVerifiedPhoneNumber():

  • getDigitalCredentialPayload() завершается с ошибкой PREFLIGHT_CHECK_FAILED или INVALID_TEST_NUMBER_ID, если сервер отклоняет тестовый токен.
  • exchangeCredentialResponseForPhoneNumber() возвращает ошибку INVALID_DIGITAL_CREDENTIAL_RESPONSE или INVALID_TEST_NUMBER_ID, если сервер отклоняет тестовый токен.
  • Ваш вызов Менеджера учетных данных выдает ошибку GetCredentialException, которую вы обрабатываете напрямую.

Неподдерживаемые устройства и SIM-карты

Если для SIM-карты isSupported() – это false, getReason() возвращает одно из следующих значений VerificationSupportStatus:

Значение Значение
INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED Оператор SIM-карты не поддерживается. Подробнее о поддерживаемых операторах связи…
INCAPABLE_DUE_TO_ANDROID_VERSION На устройстве установлена версия Android ниже 9 (уровень API 28).
INCAPABLE_DUE_TO_SIM_STATE SIM-карта не готова. Если SIM-карта заблокирована или ещё загружается, также может возвращаться значение INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED, поскольку сначала проверяется оператор.

В каждом случае используйте другой способ подтверждения, например SMS, для этой 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() – это существующий процесс подтверждения номера телефона в вашем приложении.

Дальнейшие действия