Firebase is back at Google I/O on May 10! Register now

Аутентификация в Firebase на Android по номеру телефона

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.

Вы можете использовать Firebase Authentication для входа пользователя, отправив SMS-сообщение на телефон пользователя. Пользователь входит в систему, используя одноразовый код, содержащийся в SMS-сообщении.

Самый простой способ добавить вход по номеру телефона в ваше приложение — использовать FirebaseUI , который включает в себя виджет для входа в систему, который реализует потоки входа для входа по номеру телефона, а также основанный на пароле и федеративный вход. -в. В этом документе описывается, как реализовать процесс входа по номеру телефона с помощью Firebase SDK.

Прежде чем вы начнете

  1. Если вы еще этого не сделали, добавьте Firebase в свой проект Android .
  2. В файле Gradle вашего модуля (на уровне приложения) (обычно <project>/<app-module>/build.gradle ) добавьте зависимость для библиотеки Firebase Authentication Android. Мы рекомендуем использовать Firebase Android BoM для управления версиями библиотеки.

    Kotlin+KTX

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:31.4.0')
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth-ktx'
    }
    

    Используя Firebase Android BoM , ваше приложение всегда будет использовать совместимые версии библиотек Firebase Android.

    (Альтернатива) Добавить зависимости библиотеки Firebase без использования BoM

    Если вы решите не использовать Firebase BoM, вы должны указать каждую версию библиотеки Firebase в строке зависимостей.

    Обратите внимание: если вы используете несколько библиотек Firebase в своем приложении, мы настоятельно рекомендуем использовать BoM для управления версиями библиотек, что гарантирует совместимость всех версий.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth-ktx:21.2.0'
    }
    

    Java

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:31.4.0')
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth'
    }
    

    Используя Firebase Android BoM , ваше приложение всегда будет использовать совместимые версии библиотек Firebase Android.

    (Альтернатива) Добавить зависимости библиотеки Firebase без использования BoM

    Если вы решите не использовать Firebase BoM, вы должны указать каждую версию библиотеки Firebase в строке зависимостей.

    Обратите внимание: если вы используете несколько библиотек Firebase в своем приложении, мы настоятельно рекомендуем использовать BoM для управления версиями библиотек, что гарантирует совместимость всех версий.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth:21.2.0'
    }
    
  3. Если вы еще не подключили свое приложение к проекту Firebase, сделайте это из консоли Firebase .
  4. Если вы еще не установили хэш SHA-1 своего приложения в консоли Firebase , сделайте это. См. Аутентификация вашего клиента для получения информации о поиске хэша SHA-1 вашего приложения.

Вопросы безопасности

Аутентификация с использованием только номера телефона, хотя и удобна, менее безопасна, чем другие доступные методы, поскольку владение номером телефона может легко передаваться между пользователями. Кроме того, на устройствах с несколькими профилями пользователей любой пользователь, который может получать SMS-сообщения, может войти в учетную запись, используя номер телефона устройства.

Если вы используете вход по номеру телефона в своем приложении, вы должны предлагать его наряду с более безопасными методами входа и информировать пользователей о компромиссах безопасности при использовании входа по номеру телефона.

Включите вход по номеру телефона для вашего проекта Firebase

Чтобы входить в систему с помощью SMS, вы должны сначала включить метод входа по номеру телефона для своего проекта Firebase:

  1. В консоли Firebase откройте раздел Аутентификация .
  2. На странице «Метод входа» включите метод входа «Номер телефона» .

Квота запросов на вход по номеру телефона в Firebase достаточно высока, чтобы не затронуть большинство приложений. Однако, если вам нужно войти в систему очень большого количества пользователей с помощью аутентификации по телефону, вам может потребоваться обновить тарифный план. Смотрите страницу с ценами .

Включить проверку приложений

Чтобы использовать аутентификацию по номеру телефона, Firebase должен иметь возможность проверять, что запросы на вход по номеру телефона поступают из вашего приложения. Существует три способа аутентификации Firebase:

  • Play Integrity API : если у пользователя есть устройство с установленными сервисами Google Play, а Firebase Authentication может подтвердить подлинность устройства с помощью Play Integrity API , можно продолжить вход по номеру телефона. Play Integrity API включен в проекте, принадлежащем Google, с помощью Firebase Authentication, а не в вашем проекте. Это не влияет на квоты Play Integrity API в вашем проекте. Поддержка целостности игры доступна в Authentication SDK v21.2.0+ (Firebase BoM v31.4.0+).

    Чтобы использовать Play Integrity, если вы еще не указали отпечаток пальца SHA-256 своего приложения, сделайте это в настройках проекта консоли Firebase. Подробнее о том, как получить отпечаток SHA-256 вашего приложения, см. в разделе Аутентификация вашего клиента .

  • SafetyNet : если у пользователя есть устройство с установленными сервисами Google Play, а Firebase Authentication может подтвердить подлинность устройства с помощью Android SafetyNet , можно продолжить вход по номеру телефона.
  • Проверка reCAPTCHA . В случае невозможности использования Play Integrity или SafetyNet, например, если у пользователя есть устройство без установленных сервисов Google Play, Firebase Authentication использует проверку reCAPTCHA для завершения процесса входа в систему по телефону. Задача reCAPTCHA часто может быть выполнена без того, чтобы пользователю приходилось что-либо решать. Обратите внимание, что этот поток требует, чтобы SHA-1 был связан с вашим приложением. Этот поток также требует, чтобы ваш ключ API был неограниченным или внесенным в белый список для PROJECT_ID .firebaseapp.com .
Вы можете принудительно выполнить поток проверки reCAPTCHA с помощью forceRecaptchaFlowForTesting Вы можете отключить проверку приложения (при использовании вымышленных телефонных номеров) с помощью setAppVerificationDisabledForTesting .

Отправить код подтверждения на телефон пользователя

Чтобы инициировать вход по номеру телефона, предоставьте пользователю интерфейс, предлагающий ввести свой номер телефона. Юридические требования различаются, но в качестве наилучшей практики и для установления ожиданий для ваших пользователей вы должны сообщить им, что если они используют вход с помощью телефона, они могут получить SMS-сообщение для подтверждения, и применяются стандартные тарифы.

Затем передайте их номер телефона методу PhoneAuthProvider.verifyPhoneNumber , чтобы запросить у Firebase проверку номера телефона пользователя. Например:

Kotlin+KTX

val options = PhoneAuthOptions.newBuilder(auth)
    .setPhoneNumber(phoneNumber)       // Phone number to verify
    .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
    .setActivity(this)                 // Activity (for callback binding)
    .setCallbacks(callbacks)          // OnVerificationStateChangedCallbacks
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

Java

PhoneAuthOptions options = 
  PhoneAuthOptions.newBuilder(mAuth) 
      .setPhoneNumber(phoneNumber)       // Phone number to verify
      .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
      .setActivity(this)                 // (optional) Activity for callback binding
      // If no activity is passed, reCAPTCHA verification can not be used.
      .setCallbacks(mCallbacks)          // OnVerificationStateChangedCallbacks
      .build();
  PhoneAuthProvider.verifyPhoneNumber(options);     

Метод verifyPhoneNumber является реентерабельным: если вы вызываете его несколько раз, например, в методе onStart действия, метод verifyPhoneNumber не будет отправлять второе SMS, если не истекло время ожидания исходного запроса.

Вы можете использовать это поведение, чтобы возобновить процесс входа по номеру телефона, если ваше приложение закрывается до того, как пользователь сможет войти в систему (например, когда пользователь использует свое приложение SMS). После вызова verifyPhoneNumber установите флаг, указывающий, что проверка выполняется. Затем сохраните флаг в методе onSaveInstanceState вашей Activity и восстановите флаг в onRestoreInstanceState . Наконец, в методе onStart вашей Activity проверьте, выполняется ли уже проверка, и если да, снова вызовите verifyPhoneNumber . Не забудьте снять флаг, когда проверка завершится или завершится ошибкой (см. Обратные вызовы проверки ).

Чтобы легко обрабатывать поворот экрана и другие случаи перезапуска Activity, передайте Activity методу verifyPhoneNumber . Обратные вызовы будут автоматически отключены при остановке действия, поэтому вы можете свободно писать код перехода пользовательского интерфейса в методах обратного вызова.

SMS-сообщение, отправленное Firebase, также можно локализовать, указав язык аутентификации с помощью метода setLanguageCode в вашем экземпляре Auth.

Kotlin+KTX

auth.setLanguageCode("fr")
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage()

Java

auth.setLanguageCode("fr");
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage();

При вызове PhoneAuthProvider.verifyPhoneNumber необходимо также предоставить экземпляр OnVerificationStateChangedCallbacks , который содержит реализации функций обратного вызова, обрабатывающих результаты запроса. Например:

Kotlin+KTX

callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    override fun onVerificationCompleted(credential: PhoneAuthCredential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:$credential")
        signInWithPhoneAuthCredential(credential)
    }

    override fun onVerificationFailed(e: FirebaseException) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e)

        if (e is FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e is FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e is FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    override fun onCodeSent(
        verificationId: String,
        token: PhoneAuthProvider.ForceResendingToken
    ) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:$verificationId")

        // Save verification ID and resending token so we can use them later
        storedVerificationId = verificationId
        resendToken = token
    }
}

Java

mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    @Override
    public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:" + credential);

        signInWithPhoneAuthCredential(credential);
    }

    @Override
    public void onVerificationFailed(@NonNull FirebaseException e) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e);

        if (e instanceof FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e instanceof FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e instanceof FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    @Override
    public void onCodeSent(@NonNull String verificationId,
                           @NonNull PhoneAuthProvider.ForceResendingToken token) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:" + verificationId);

        // Save verification ID and resending token so we can use them later
        mVerificationId = verificationId;
        mResendToken = token;
    }
};

Проверочные обратные вызовы

В большинстве приложений вы реализуете обратные вызовы onVerificationCompleted , onVerificationFailed и onCodeSent . Вы также можете реализовать onCodeAutoRetrievalTimeOut в зависимости от требований вашего приложения.

onVerificationCompleted (PhoneAuthCredential)

Этот метод вызывается в двух случаях:

  • Мгновенная проверка: в некоторых случаях номер телефона может быть проверен мгновенно без отправки или ввода кода подтверждения.
  • Автоматическое получение: на некоторых устройствах сервисы Google Play могут автоматически обнаруживать входящие SMS с подтверждением и выполнять проверку без участия пользователя. (Эта возможность может быть недоступна у некоторых операторов связи.) При этом используется SMS Retriever API , который включает 11-символьный хэш в конце SMS-сообщения.
В любом случае номер телефона пользователя был успешно проверен, и вы можете использовать объект PhoneAuthCredential , переданный обратному вызову, для входа пользователя .

onVerificationFailed (исключение FirebaseException)

Этот метод вызывается в ответ на недопустимый запрос подтверждения, например запрос, в котором указан неверный номер телефона или код подтверждения.

onCodeSent (верификационный идентификатор строки, PhoneAuthProvider.ForceResendingToken)

Необязательный. Этот метод вызывается после того, как проверочный код был отправлен по SMS на указанный номер телефона.

При вызове этого метода в большинстве приложений отображается пользовательский интерфейс, предлагающий пользователю ввести код подтверждения из SMS-сообщения. (В то же время автоматическая проверка может выполняться в фоновом режиме.) Затем, после того как пользователь введет код подтверждения, вы можете использовать код подтверждения и идентификатор подтверждения, которые были переданы методу, для создания объекта PhoneAuthCredential , который вы можете, в свою очередь, использовать для входа пользователя. Однако некоторые приложения могут ждать, пока не будет вызван onCodeAutoRetrievalTimeOut , прежде чем отобразить пользовательский интерфейс кода подтверждения (не рекомендуется).

onCodeAutoRetrievalTimeOut (верификационный идентификатор строки)

Необязательный. Этот метод вызывается по истечении времени ожидания, указанного для verifyPhoneNumber , без предварительного запуска onVerificationCompleted . На устройствах без SIM-карт этот метод вызывается сразу, потому что автозагрузка SMS невозможна.

Некоторые приложения блокируют ввод данных пользователем до истечения периода автоматической проверки и только после этого отображают пользовательский интерфейс, предлагающий пользователю ввести код подтверждения из SMS-сообщения (не рекомендуется).

Создайте объект PhoneAuthCredential

После того, как пользователь введет код подтверждения, отправленный Firebase на телефон пользователя, создайте объект PhoneAuthCredential , используя код подтверждения и идентификатор подтверждения, который был передан в обратный вызов onCodeSent или onCodeAutoRetrievalTimeOut . (При вызове onVerificationCompleted вы напрямую получаете объект PhoneAuthCredential , поэтому этот шаг можно пропустить.)

Чтобы создать объект PhoneAuthCredential , вызовите PhoneAuthProvider.getCredential :

Kotlin+KTX

val credential = PhoneAuthProvider.getCredential(verificationId!!, code)

Java

PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);

Войти пользователем

После получения объекта PhoneAuthCredential , будь то в обратном вызове onVerificationCompleted или вызовом PhoneAuthProvider.getCredential , завершите процесс входа, передав объект PhoneAuthCredential в FirebaseAuth.signInWithCredential :

Kotlin+KTX

private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
    auth.signInWithCredential(credential)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCredential:success")

                    val user = task.result?.user
                } else {
                    // Sign in failed, display a message and update the UI
                    Log.w(TAG, "signInWithCredential:failure", task.exception)
                    if (task.exception is FirebaseAuthInvalidCredentialsException) {
                        // The verification code entered was invalid
                    }
                    // Update UI
                }
            }
}

Java

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Sign in success, update UI with the signed-in user's information
                        Log.d(TAG, "signInWithCredential:success");

                        FirebaseUser user = task.getResult().getUser();
                        // Update UI
                    } else {
                        // Sign in failed, display a message and update the UI
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid
                        }
                    }
                }
            });
}

Тест с вымышленными телефонными номерами

Вы можете настроить вымышленные номера телефонов для разработки через консоль Firebase. Тестирование с вымышленными телефонными номерами дает следующие преимущества:

  • Протестируйте аутентификацию по номеру телефона, не расходуя квоту использования.
  • Протестируйте аутентификацию по номеру телефона без отправки фактического SMS-сообщения.
  • Выполняйте последовательные тесты с одним и тем же номером телефона без ограничения скорости. Это сводит к минимуму риск отклонения во время процесса проверки в магазине приложений, если рецензент использует один и тот же номер телефона для тестирования.
  • Легко тестируйте в средах разработки без каких-либо дополнительных усилий, таких как возможность разработки в симуляторе iOS или эмуляторе Android без сервисов Google Play.
  • Напишите интеграционные тесты, не блокируя проверки безопасности, которые обычно применяются к реальным телефонным номерам в производственной среде.

Вымышленные номера телефонов должны соответствовать следующим требованиям:

  1. Убедитесь, что вы используете номера телефонов, которые действительно вымышлены и еще не существуют. Firebase Authentication не позволяет вам устанавливать существующие телефонные номера, используемые реальными пользователями, в качестве тестовых номеров. Один из вариантов — использовать номера с префиксом 555 в качестве тестовых номеров телефонов в США, например: +1 650-555-3434 .
  2. Телефонные номера должны быть правильно отформатированы по длине и другим ограничениям. Они по-прежнему будут проходить ту же проверку, что и реальный номер телефона пользователя.
  3. Вы можете добавить до 10 номеров телефонов для разработки.
  4. Используйте тестовые телефонные номера/коды, которые трудно угадать, и часто меняйте их.

Создавайте вымышленные номера телефонов и коды подтверждения

  1. В консоли Firebase откройте раздел Аутентификация .
  2. На вкладке «Метод входа» включите поставщика услуг телефона, если вы еще этого не сделали.
  3. Откройте меню Телефонные номера для тестирования аккордеона.
  4. Укажите номер телефона, который вы хотите проверить, например: +1 650-555-3434 .
  5. Укажите 6-значный код подтверждения для этого конкретного номера, например: 654321 .
  6. Добавьте число. При необходимости вы можете удалить номер телефона и его код, наведя курсор на соответствующую строку и нажав значок корзины.

Ручное тестирование

Вы можете напрямую начать использовать вымышленный номер телефона в своем приложении. Это позволяет выполнять ручное тестирование на этапах разработки, не сталкиваясь с проблемами квот или регулирования. Вы также можете протестировать непосредственно из симулятора iOS или эмулятора Android без установленных сервисов Google Play.

Когда вы указываете вымышленный номер телефона и отправляете код подтверждения, фактическое SMS не отправляется. Вместо этого вам необходимо предоставить ранее настроенный проверочный код, чтобы завершить вход.

По завершении входа создается пользователь Firebase с этим номером телефона. Пользователь имеет то же поведение и свойства, что и пользователь с реальным номером телефона, и может таким же образом получать доступ к базе данных реального времени/облаку Firestore и другим службам. Идентификационный токен, созданный в ходе этого процесса, имеет ту же подпись, что и реальный пользователь номера телефона.

Другой вариант — установить тестовую роль с помощью пользовательских утверждений для этих пользователей, чтобы отличить их от поддельных пользователей, если вы хотите еще больше ограничить доступ.

Чтобы вручную запустить поток reCAPTCHA для тестирования, используйте метод forceRecaptchaFlowForTesting() .

// Force reCAPTCHA flow
FirebaseAuth.getInstance().getFirebaseAuthSettings().forceRecaptchaFlowForTesting();

Интеграционное тестирование

В дополнение к ручному тестированию Firebase Authentication предоставляет API-интерфейсы, помогающие писать интеграционные тесты для тестирования аутентификации по телефону. Эти API отключают проверку приложений, отключая требование reCAPTCHA в Интернете и автоматические push-уведомления в iOS. Это делает возможным автоматическое тестирование в этих потоках и упрощает его реализацию. Кроме того, они помогают обеспечить возможность тестирования потоков мгновенной проверки на Android.

В Android вызовите setAppVerificationDisabledForTesting() перед вызовом signInWithPhoneNumber . Это отключает автоматическую проверку приложения, позволяя вам передавать номер телефона, не решая его вручную. Несмотря на то, что Play Integrity, SafetyNet и reCAPTCHA отключены, использование реального номера телефона не позволит завершить вход. С этим API можно использовать только вымышленные номера телефонов.

// Turn off phone auth app verification.
FirebaseAuth.getInstance().getFirebaseAuthSettings()
   .setAppVerificationDisabledForTesting();

Вызов verifyPhoneNumber с вымышленным номером вызывает обратный вызов onCodeSent , в котором вам нужно будет предоставить соответствующий код подтверждения. Это позволяет проводить тестирование в эмуляторах Android.

Java

String phoneNum = "+16505554567";
String testVerificationCode = "123456";

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
FirebaseAuth auth = FirebaseAuth.getInstance();
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(auth)
        .setPhoneNumber(phoneNum)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onCodeSent(@NonNull String verificationId,
                                   @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
                // Save the verification id somewhere
                // ...

                // The corresponding whitelisted code above should be used to complete sign-in.
                MainActivity.this.enableUserManuallyInputCode();
            }

            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
                // Sign in with the credential
                // ...
            }

            @Override
            public void onVerificationFailed(@NonNull FirebaseException e) {
                // ...
            }
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin+KTX

val phoneNum = "+16505554567"
val testVerificationCode = "123456"

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
val options = PhoneAuthOptions.newBuilder(Firebase.auth)
        .setPhoneNumber(phoneNum)
        .setTimeout(30L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

            override fun onCodeSent(
                    verificationId: String,
                    forceResendingToken: PhoneAuthProvider.ForceResendingToken
            ) {
                // Save the verification id somewhere
                // ...

                // The corresponding whitelisted code above should be used to complete sign-in.
                this@MainActivity.enableUserManuallyInputCode()
            }

            override fun onVerificationCompleted(phoneAuthCredential: PhoneAuthCredential) {
                // Sign in with the credential
                // ...
            }

            override fun onVerificationFailed(e: FirebaseException) {
                // ...
            }
        })
        .build()
PhoneAuthProvider.verifyPhoneNumber(options)

Кроме того, вы можете протестировать потоки автозагрузки в Android, установив вымышленный номер и соответствующий ему проверочный код для автозагрузки, вызвав setAutoRetrievedSmsCodeForPhoneNumber .

Когда вызывается verifyPhoneNumber , он срабатывает onVerificationCompleted напрямую с PhoneAuthCredential . Это работает только с вымышленными телефонными номерами.

Убедитесь, что эта функция отключена и в вашем приложении нет жестко закодированных вымышленных телефонных номеров при публикации приложения в магазине Google Play.

Java

// The test phone number and code should be whitelisted in the console.
String phoneNumber = "+16505554567";
String smsCode = "123456";

FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
FirebaseAuthSettings firebaseAuthSettings = firebaseAuth.getFirebaseAuthSettings();

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode);

PhoneAuthOptions options = PhoneAuthOptions.newBuilder(firebaseAuth)
        .setPhoneNumber(phoneNumber)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
                // Instant verification is applied and a credential is directly returned.
                // ...
            }

            // ...
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin+KTX

// The test phone number and code should be whitelisted in the console.
val phoneNumber = "+16505554567"
val smsCode = "123456"

val firebaseAuth = Firebase.auth
val firebaseAuthSettings = firebaseAuth.firebaseAuthSettings

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode)

val options = PhoneAuthOptions.newBuilder(firebaseAuth)
        .setPhoneNumber(phoneNumber)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            override fun onVerificationCompleted(credential: PhoneAuthCredential) {
                // Instant verification is applied and a credential is directly returned.
                // ...
            }

            // ...
        })
        .build()
PhoneAuthProvider.verifyPhoneNumber(options)

Следующие шаги

После того, как пользователь входит в систему в первый раз, создается новая учетная запись пользователя и связывается с учетными данными, т. е. с именем пользователя и паролем, номером телефона или информацией о поставщике проверки подлинности, с которыми пользователь вошел в систему. Эта новая учетная запись хранится как часть вашего проекта Firebase и может использоваться для идентификации пользователя во всех приложениях вашего проекта, независимо от того, как пользователь входит в систему.

  • В своих приложениях вы можете получить основную информацию о профиле пользователя из объекта FirebaseUser . См. Управление пользователями .

  • В правилах безопасности базы данных Firebase Realtime и облачного хранилища вы можете получить уникальный идентификатор пользователя, вошедшего в систему, из переменной auth и использовать его для управления тем, к каким данным пользователь может получить доступ.

Вы можете разрешить пользователям входить в ваше приложение с помощью нескольких поставщиков проверки подлинности, связав учетные данные поставщика проверки подлинности с существующей учетной записью пользователя.

Чтобы выйти из системы, вызовите signOut :

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();
,

Вы можете использовать Firebase Authentication для входа пользователя, отправив SMS-сообщение на телефон пользователя. Пользователь входит в систему, используя одноразовый код, содержащийся в SMS-сообщении.

Самый простой способ добавить вход по номеру телефона в ваше приложение — использовать FirebaseUI , который включает в себя виджет для входа в систему, который реализует потоки входа для входа по номеру телефона, а также основанный на пароле и федеративный вход. -в. В этом документе описывается, как реализовать процесс входа по номеру телефона с помощью Firebase SDK.

Прежде чем вы начнете

  1. Если вы еще этого не сделали, добавьте Firebase в свой проект Android .
  2. В файле Gradle вашего модуля (на уровне приложения) (обычно <project>/<app-module>/build.gradle ) добавьте зависимость для библиотеки Firebase Authentication Android. Мы рекомендуем использовать Firebase Android BoM для управления версиями библиотеки.

    Kotlin+KTX

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:31.4.0')
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth-ktx'
    }
    

    Используя Firebase Android BoM , ваше приложение всегда будет использовать совместимые версии библиотек Firebase Android.

    (Альтернатива) Добавить зависимости библиотеки Firebase без использования BoM

    Если вы решите не использовать Firebase BoM, вы должны указать каждую версию библиотеки Firebase в строке зависимостей.

    Обратите внимание: если вы используете несколько библиотек Firebase в своем приложении, мы настоятельно рекомендуем использовать BoM для управления версиями библиотек, что гарантирует совместимость всех версий.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth-ktx:21.2.0'
    }
    

    Java

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:31.4.0')
    
        // Add the dependency for the Firebase Authentication library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth'
    }
    

    Используя Firebase Android BoM , ваше приложение всегда будет использовать совместимые версии библиотек Firebase Android.

    (Альтернатива) Добавить зависимости библиотеки Firebase без использования BoM

    Если вы решите не использовать Firebase BoM, вы должны указать каждую версию библиотеки Firebase в строке зависимостей.

    Обратите внимание: если вы используете несколько библиотек Firebase в своем приложении, мы настоятельно рекомендуем использовать BoM для управления версиями библиотек, что гарантирует совместимость всех версий.

    dependencies {
        // Add the dependency for the Firebase Authentication library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-auth:21.2.0'
    }
    
  3. Если вы еще не подключили свое приложение к проекту Firebase, сделайте это из консоли Firebase .
  4. Если вы еще не установили хэш SHA-1 своего приложения в консоли Firebase , сделайте это. См. Аутентификация вашего клиента для получения информации о поиске хэша SHA-1 вашего приложения.

Вопросы безопасности

Аутентификация с использованием только номера телефона, хотя и удобна, менее безопасна, чем другие доступные методы, поскольку владение номером телефона может легко передаваться между пользователями. Кроме того, на устройствах с несколькими профилями пользователей любой пользователь, который может получать SMS-сообщения, может войти в учетную запись, используя номер телефона устройства.

Если вы используете вход по номеру телефона в своем приложении, вы должны предлагать его наряду с более безопасными методами входа и информировать пользователей о компромиссах безопасности при использовании входа по номеру телефона.

Включите вход по номеру телефона для вашего проекта Firebase

Чтобы входить в систему с помощью SMS, вы должны сначала включить метод входа по номеру телефона для своего проекта Firebase:

  1. В консоли Firebase откройте раздел Аутентификация .
  2. На странице «Метод входа» включите метод входа «Номер телефона» .

Квота запросов на вход по номеру телефона в Firebase достаточно высока, чтобы не затронуть большинство приложений. Однако, если вам нужно войти в систему очень большого количества пользователей с помощью аутентификации по телефону, вам может потребоваться обновить тарифный план. Смотрите страницу с ценами .

Включить проверку приложений

Чтобы использовать аутентификацию по номеру телефона, Firebase должен иметь возможность проверять, что запросы на вход по номеру телефона поступают из вашего приложения. Существует три способа аутентификации Firebase:

  • Play Integrity API : если у пользователя есть устройство с установленными сервисами Google Play, а Firebase Authentication может подтвердить подлинность устройства с помощью Play Integrity API , можно продолжить вход по номеру телефона. Play Integrity API включен в проекте, принадлежащем Google, с помощью Firebase Authentication, а не в вашем проекте. Это не влияет на квоты Play Integrity API в вашем проекте. Поддержка целостности игры доступна в Authentication SDK v21.2.0+ (Firebase BoM v31.4.0+).

    Чтобы использовать Play Integrity, если вы еще не указали отпечаток пальца SHA-256 своего приложения, сделайте это в настройках проекта консоли Firebase. Подробнее о том, как получить отпечаток SHA-256 вашего приложения, см. в разделе Аутентификация вашего клиента .

  • SafetyNet : если у пользователя есть устройство с установленными сервисами Google Play, а Firebase Authentication может подтвердить подлинность устройства с помощью Android SafetyNet , можно продолжить вход по номеру телефона.
  • Проверка reCAPTCHA . В случае невозможности использования Play Integrity или SafetyNet, например, если у пользователя есть устройство без установленных сервисов Google Play, Firebase Authentication использует проверку reCAPTCHA для завершения процесса входа в систему по телефону. Задача reCAPTCHA часто может быть выполнена без того, чтобы пользователю приходилось что-либо решать. Обратите внимание, что этот поток требует, чтобы SHA-1 был связан с вашим приложением. Этот поток также требует, чтобы ваш ключ API был неограниченным или внесенным в белый список для PROJECT_ID .firebaseapp.com .
Вы можете принудительно выполнить поток проверки reCAPTCHA с помощью forceRecaptchaFlowForTesting Вы можете отключить проверку приложения (при использовании вымышленных телефонных номеров) с помощью setAppVerificationDisabledForTesting .

Отправить код подтверждения на телефон пользователя

Чтобы инициировать вход по номеру телефона, предоставьте пользователю интерфейс, предлагающий ввести свой номер телефона. Юридические требования различаются, но в качестве наилучшей практики и для установления ожиданий для ваших пользователей вы должны сообщить им, что если они используют вход с помощью телефона, они могут получить SMS-сообщение для подтверждения, и применяются стандартные тарифы.

Затем передайте их номер телефона методу PhoneAuthProvider.verifyPhoneNumber , чтобы запросить у Firebase проверку номера телефона пользователя. Например:

Kotlin+KTX

val options = PhoneAuthOptions.newBuilder(auth)
    .setPhoneNumber(phoneNumber)       // Phone number to verify
    .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
    .setActivity(this)                 // Activity (for callback binding)
    .setCallbacks(callbacks)          // OnVerificationStateChangedCallbacks
    .build()
PhoneAuthProvider.verifyPhoneNumber(options)

Java

PhoneAuthOptions options = 
  PhoneAuthOptions.newBuilder(mAuth) 
      .setPhoneNumber(phoneNumber)       // Phone number to verify
      .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
      .setActivity(this)                 // (optional) Activity for callback binding
      // If no activity is passed, reCAPTCHA verification can not be used.
      .setCallbacks(mCallbacks)          // OnVerificationStateChangedCallbacks
      .build();
  PhoneAuthProvider.verifyPhoneNumber(options);     

Метод verifyPhoneNumber является реентерабельным: если вы вызываете его несколько раз, например, в методе onStart действия, метод verifyPhoneNumber не будет отправлять второе SMS, если не истекло время ожидания исходного запроса.

Вы можете использовать это поведение, чтобы возобновить процесс входа по номеру телефона, если ваше приложение закрывается до того, как пользователь сможет войти в систему (например, когда пользователь использует свое приложение SMS). После вызова verifyPhoneNumber установите флаг, указывающий, что проверка выполняется. Затем сохраните флаг в методе onSaveInstanceState вашей Activity и восстановите флаг в onRestoreInstanceState . Наконец, в методе onStart вашей Activity проверьте, выполняется ли уже проверка, и если да, снова вызовите verifyPhoneNumber . Не забудьте снять флаг, когда проверка завершится или завершится ошибкой (см. Обратные вызовы проверки ).

Чтобы легко обрабатывать поворот экрана и другие случаи перезапуска Activity, передайте Activity методу verifyPhoneNumber . Обратные вызовы будут автоматически отключены при остановке действия, поэтому вы можете свободно писать код перехода пользовательского интерфейса в методах обратного вызова.

SMS-сообщение, отправленное Firebase, также можно локализовать, указав язык аутентификации с помощью метода setLanguageCode в вашем экземпляре Auth.

Kotlin+KTX

auth.setLanguageCode("fr")
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage()

Java

auth.setLanguageCode("fr");
// To apply the default app language instead of explicitly setting it.
// auth.useAppLanguage();

При вызове PhoneAuthProvider.verifyPhoneNumber необходимо также предоставить экземпляр OnVerificationStateChangedCallbacks , который содержит реализации функций обратного вызова, обрабатывающих результаты запроса. Например:

Kotlin+KTX

callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    override fun onVerificationCompleted(credential: PhoneAuthCredential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:$credential")
        signInWithPhoneAuthCredential(credential)
    }

    override fun onVerificationFailed(e: FirebaseException) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e)

        if (e is FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e is FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e is FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    override fun onCodeSent(
        verificationId: String,
        token: PhoneAuthProvider.ForceResendingToken
    ) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:$verificationId")

        // Save verification ID and resending token so we can use them later
        storedVerificationId = verificationId
        resendToken = token
    }
}

Java

mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    @Override
    public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:" + credential);

        signInWithPhoneAuthCredential(credential);
    }

    @Override
    public void onVerificationFailed(@NonNull FirebaseException e) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e);

        if (e instanceof FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e instanceof FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        } else if (e instanceof FirebaseAuthMissingActivityForRecaptchaException) {
            // reCAPTCHA verification attempted with null Activity
        }

        // Show a message and update the UI
    }

    @Override
    public void onCodeSent(@NonNull String verificationId,
                           @NonNull PhoneAuthProvider.ForceResendingToken token) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:" + verificationId);

        // Save verification ID and resending token so we can use them later
        mVerificationId = verificationId;
        mResendToken = token;
    }
};

Проверочные обратные вызовы

В большинстве приложений вы реализуете обратные вызовы onVerificationCompleted , onVerificationFailed и onCodeSent . Вы также можете реализовать onCodeAutoRetrievalTimeOut в зависимости от требований вашего приложения.

onVerificationCompleted (PhoneAuthCredential)

Этот метод вызывается в двух случаях:

  • Мгновенная проверка: в некоторых случаях номер телефона может быть проверен мгновенно без отправки или ввода кода подтверждения.
  • Автоматическое получение: на некоторых устройствах сервисы Google Play могут автоматически обнаруживать входящие SMS с подтверждением и выполнять проверку без участия пользователя. (Эта возможность может быть недоступна у некоторых операторов связи.) При этом используется SMS Retriever API , который включает 11-символьный хэш в конце SMS-сообщения.
В любом случае номер телефона пользователя был успешно проверен, и вы можете использовать объект PhoneAuthCredential , переданный обратному вызову, для входа пользователя .

onVerificationFailed (исключение FirebaseException)

Этот метод вызывается в ответ на недопустимый запрос подтверждения, например запрос, в котором указан неверный номер телефона или код подтверждения.

onCodeSent (верификационный идентификатор строки, PhoneAuthProvider.ForceResendingToken)

Необязательный. Этот метод вызывается после того, как проверочный код был отправлен по SMS на указанный номер телефона.

При вызове этого метода в большинстве приложений отображается пользовательский интерфейс, предлагающий пользователю ввести код подтверждения из SMS-сообщения. (В то же время автоматическая проверка может выполняться в фоновом режиме.) Затем, после того как пользователь введет код подтверждения, вы можете использовать код подтверждения и идентификатор подтверждения, которые были переданы методу, для создания объекта PhoneAuthCredential , который вы можете, в свою очередь, использовать для входа пользователя. Однако некоторые приложения могут ждать, пока не будет вызван onCodeAutoRetrievalTimeOut , прежде чем отобразить пользовательский интерфейс кода подтверждения (не рекомендуется).

onCodeAutoRetrievalTimeOut (верификационный идентификатор строки)

Необязательный. Этот метод вызывается по истечении времени ожидания, указанного для verifyPhoneNumber , без предварительного запуска onVerificationCompleted . На устройствах без SIM-карт этот метод вызывается сразу, потому что автозагрузка SMS невозможна.

Некоторые приложения блокируют ввод данных пользователем до истечения периода автоматической проверки и только после этого отображают пользовательский интерфейс, предлагающий пользователю ввести код подтверждения из SMS-сообщения (не рекомендуется).

Создайте объект PhoneAuthCredential

После того, как пользователь введет код подтверждения, отправленный Firebase на телефон пользователя, создайте объект PhoneAuthCredential , используя код подтверждения и идентификатор подтверждения, который был передан в обратный вызов onCodeSent или onCodeAutoRetrievalTimeOut . (При вызове onVerificationCompleted вы напрямую получаете объект PhoneAuthCredential , поэтому этот шаг можно пропустить.)

Чтобы создать объект PhoneAuthCredential , вызовите PhoneAuthProvider.getCredential :

Kotlin+KTX

val credential = PhoneAuthProvider.getCredential(verificationId!!, code)

Java

PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);

Войти пользователем

После получения объекта PhoneAuthCredential , будь то в обратном вызове onVerificationCompleted или вызовом PhoneAuthProvider.getCredential , завершите процесс входа, передав объект PhoneAuthCredential в FirebaseAuth.signInWithCredential :

Kotlin+KTX

private fun signInWithPhoneAuthCredential(credential: PhoneAuthCredential) {
    auth.signInWithCredential(credential)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCredential:success")

                    val user = task.result?.user
                } else {
                    // Sign in failed, display a message and update the UI
                    Log.w(TAG, "signInWithCredential:failure", task.exception)
                    if (task.exception is FirebaseAuthInvalidCredentialsException) {
                        // The verification code entered was invalid
                    }
                    // Update UI
                }
            }
}

Java

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Sign in success, update UI with the signed-in user's information
                        Log.d(TAG, "signInWithCredential:success");

                        FirebaseUser user = task.getResult().getUser();
                        // Update UI
                    } else {
                        // Sign in failed, display a message and update the UI
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid
                        }
                    }
                }
            });
}

Тест с вымышленными телефонными номерами

Вы можете настроить вымышленные номера телефонов для разработки через консоль Firebase. Тестирование с вымышленными телефонными номерами дает следующие преимущества:

  • Протестируйте аутентификацию по номеру телефона, не расходуя квоту использования.
  • Протестируйте аутентификацию по номеру телефона без отправки фактического SMS-сообщения.
  • Выполняйте последовательные тесты с одним и тем же номером телефона без ограничения скорости. Это сводит к минимуму риск отклонения во время процесса проверки в магазине приложений, если рецензент использует один и тот же номер телефона для тестирования.
  • Легко тестируйте в средах разработки без каких-либо дополнительных усилий, таких как возможность разработки в симуляторе iOS или эмуляторе Android без сервисов Google Play.
  • Напишите интеграционные тесты, не блокируя проверки безопасности, которые обычно применяются к реальным телефонным номерам в производственной среде.

Вымышленные номера телефонов должны соответствовать следующим требованиям:

  1. Убедитесь, что вы используете номера телефонов, которые действительно вымышлены и еще не существуют. Firebase Authentication не позволяет вам устанавливать существующие телефонные номера, используемые реальными пользователями, в качестве тестовых номеров. Один из вариантов — использовать номера с префиксом 555 в качестве тестовых номеров телефонов в США, например: +1 650-555-3434 .
  2. Телефонные номера должны быть правильно отформатированы по длине и другим ограничениям. Они по-прежнему будут проходить ту же проверку, что и реальный номер телефона пользователя.
  3. Вы можете добавить до 10 номеров телефонов для развития.
  4. Use test phone numbers/codes that are hard to guess and change those frequently.

Create fictional phone numbers and verification codes

  1. In the Firebase console , open the Authentication section.
  2. In the Sign in method tab, enable the Phone provider if you haven't already.
  3. Open the Phone numbers for testing accordion menu.
  4. Provide the phone number you want to test, for example: +1 650-555-3434 .
  5. Provide the 6-digit verification code for that specific number, for example: 654321 .
  6. Add the number. If there's a need, you can delete the phone number and its code by hovering over the corresponding row and clicking the trash icon.

Manual testing

You can directly start using a fictional phone number in your application. This allows you to perform manual testing during development stages without running into quota issues or throttling. You can also test directly from an iOS simulator or Android emulator without Google Play Services installed.

When you provide the fictional phone number and send the verification code, no actual SMS is sent. Instead, you need to provide the previously configured verification code to complete the sign in.

On sign-in completion, a Firebase user is created with that phone number. The user has the same behavior and properties as a real phone number user, and can access Realtime Database/Cloud Firestore and other services the same way. The ID token minted during this process has the same signature as a real phone number user.

Another option is to set a test role via custom claims on these users to differentiate them as fake users if you want to further restrict access.

To manually trigger the reCAPTCHA flow for testing, use the forceRecaptchaFlowForTesting() method.

// Force reCAPTCHA flow
FirebaseAuth.getInstance().getFirebaseAuthSettings().forceRecaptchaFlowForTesting();

Integration testing

In addition to manual testing, Firebase Authentication provides APIs to help write integration tests for phone auth testing. These APIs disable app verification by disabling the reCAPTCHA requirement in web and silent push notifications in iOS. This makes automation testing possible in these flows and easier to implement. In addition, they help provide the ability to test instant verification flows on Android.

On Android, call setAppVerificationDisabledForTesting() before the signInWithPhoneNumber call. This disables app verification automatically, allowing you to pass the phone number without manually solving it. Even though Play Integrity, SafetyNet, and reCAPTCHA are disabled, using a real phone number will still fail to complete sign in. Only fictional phone numbers can be used with this API.

// Turn off phone auth app verification.
FirebaseAuth.getInstance().getFirebaseAuthSettings()
   .setAppVerificationDisabledForTesting();

Calling verifyPhoneNumber with a fictional number triggers the onCodeSent callback, in which you'll need to provide the corresponding verification code. This allows testing in Android Emulators.

Java

String phoneNum = "+16505554567";
String testVerificationCode = "123456";

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
FirebaseAuth auth = FirebaseAuth.getInstance();
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(auth)
        .setPhoneNumber(phoneNum)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onCodeSent(@NonNull String verificationId,
                                   @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
                // Save the verification id somewhere
                // ...

                // The corresponding whitelisted code above should be used to complete sign-in.
                MainActivity.this.enableUserManuallyInputCode();
            }

            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
                // Sign in with the credential
                // ...
            }

            @Override
            public void onVerificationFailed(@NonNull FirebaseException e) {
                // ...
            }
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin+KTX

val phoneNum = "+16505554567"
val testVerificationCode = "123456"

// Whenever verification is triggered with the whitelisted number,
// provided it is not set for auto-retrieval, onCodeSent will be triggered.
val options = PhoneAuthOptions.newBuilder(Firebase.auth)
        .setPhoneNumber(phoneNum)
        .setTimeout(30L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

            override fun onCodeSent(
                    verificationId: String,
                    forceResendingToken: PhoneAuthProvider.ForceResendingToken
            ) {
                // Save the verification id somewhere
                // ...

                // The corresponding whitelisted code above should be used to complete sign-in.
                this@MainActivity.enableUserManuallyInputCode()
            }

            override fun onVerificationCompleted(phoneAuthCredential: PhoneAuthCredential) {
                // Sign in with the credential
                // ...
            }

            override fun onVerificationFailed(e: FirebaseException) {
                // ...
            }
        })
        .build()
PhoneAuthProvider.verifyPhoneNumber(options)

Additionally, you can test auto-retrieval flows in Android by setting the fictional number and its corresponding verification code for auto-retrieval by calling setAutoRetrievedSmsCodeForPhoneNumber .

When verifyPhoneNumber is called, it triggers onVerificationCompleted with the PhoneAuthCredential directly. This works only with fictional phone numbers.

Make sure this is disabled and no fictional phone numbers are hardcoded in your app when publishing your application to the Google Play store.

Java

// The test phone number and code should be whitelisted in the console.
String phoneNumber = "+16505554567";
String smsCode = "123456";

FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
FirebaseAuthSettings firebaseAuthSettings = firebaseAuth.getFirebaseAuthSettings();

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode);

PhoneAuthOptions options = PhoneAuthOptions.newBuilder(firebaseAuth)
        .setPhoneNumber(phoneNumber)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) {
                // Instant verification is applied and a credential is directly returned.
                // ...
            }

            // ...
        })
        .build();
PhoneAuthProvider.verifyPhoneNumber(options);

Kotlin+KTX

// The test phone number and code should be whitelisted in the console.
val phoneNumber = "+16505554567"
val smsCode = "123456"

val firebaseAuth = Firebase.auth
val firebaseAuthSettings = firebaseAuth.firebaseAuthSettings

// Configure faking the auto-retrieval with the whitelisted numbers.
firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber, smsCode)

val options = PhoneAuthOptions.newBuilder(firebaseAuth)
        .setPhoneNumber(phoneNumber)
        .setTimeout(60L, TimeUnit.SECONDS)
        .setActivity(this)
        .setCallbacks(object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            override fun onVerificationCompleted(credential: PhoneAuthCredential) {
                // Instant verification is applied and a credential is directly returned.
                // ...
            }

            // ...
        })
        .build()
PhoneAuthProvider.verifyPhoneNumber(options)

Next steps

After a user signs in for the first time, a new user account is created and linked to the credentials—that is, the user name and password, phone number, or auth provider information—the user signed in with. This new account is stored as part of your Firebase project, and can be used to identify a user across every app in your project, regardless of how the user signs in.

  • In your apps, you can get the user's basic profile information from the FirebaseUser object. See Manage Users .

  • In your Firebase Realtime Database and Cloud Storage Security Rules , you can get the signed-in user's unique user ID from the auth variable, and use it to control what data a user can access.

You can allow users to sign in to your app using multiple authentication providers by linking auth provider credentials to an existing user account.

To sign out a user, call signOut :

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();