This page describes how to get started using Firebase Phone Number Verification in an Android app.
See the [overview](https://firebase.google.com/docs/phone-number-verification.md.txt) for a general description of
this feature.

By following the steps on this page, you can quickly get started implementing
the user flows for Firebase PNV. For testing purposes, you will generate a
testing-only token that resolves to a fake phone number. Using this test token,
you can start adding Firebase PNV to your app without needing a billing account or a
device with a real SIM.

Once you're satisfied with the Firebase PNV user experience in your app, you can
follow some additional steps to productionize your app.

## Before you begin

- [Add Firebase to your Android project](https://firebase.google.com/docs/android/setup.md.txt) if you haven't
  already done so.

- Make sure your app meets the following requirements:

  - Your app's `minSdk` is 24 (Android 7.0) or higher.
  - The device or emulator runs Android 10 (API level 29) or higher and has Google Play services. For emulators, use an Android 10 or higher system image that includes Google Play.
  - To verify real phone numbers in production, the device must use a SIM from a [supported carrier](https://firebase.google.com/docs/phone-number-verification/pricing.md.txt#supported-carriers). Test mode, described on this page, doesn't need a real SIM.

## 1. Add the Firebase PNV library to your app

In your **module (app-level) Gradle file** (usually `<project>/<app-module>/build.gradle.kts` or `<project>/<app-module>/build.gradle`), add the dependency for the Firebase Phone Number Verification library for Android. We recommend using the [Firebase Android BoM](https://firebase.google.com/docs/android/learn-more.md.txt#bom) to control library versioning.

<br />

```
dependencies {
    // Import the BoM for the Firebase platform
    implementation(platform("com.google.firebase:firebase-bom:35.1.0"))

    // Add the dependencies for the Firebase Phone Number Verification libraries
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation("com.google.firebase:firebase-pnv")
}
```

By using the [Firebase Android BoM](https://firebase.google.com/docs/android/learn-more.md.txt#bom),
your app will always use compatible versions of Firebase Android libraries.
*(Alternative)*
Add Firebase library dependencies *without* using the BoM

If you choose not to use the Firebase BoM, you must specify each Firebase library version
in its dependency line.

**Note that if you use *multiple* Firebase libraries in your app, we strongly
recommend using the BoM to manage library versions, which ensures that all versions are
compatible.**

```groovy
dependencies {
    // Add the dependencies for the Firebase Phone Number Verification libraries
    // When NOT using the BoM, you must specify versions in Firebase library dependencies
    implementation("com.google.firebase:firebase-pnv:17.0.0")
}
```

<br />

## 2. Initialize the Firebase PNV library in test mode

1. In the Firebase console, go to the
   **Security** \> **Phone Verification** \> **Settings** \> [**Testing**
   tab](https://console.firebase.google.com/project/_/phoneverification/settings/testing?useAutoProject=true).

2. Click **Generate token** , select a country code, and then click
   **Generate token** again to create and copy your token.

   > [!NOTE]
   > **Note:** In order to generate a test token, you'll need the [Firebase Phone Number Verification Admin IAM role](https://docs.cloud.google.com/iam/docs/roles-permissions/fpnv#fpnv.admin). If you're not signed into the Firebase console as the project owner, you might need to be manually granted this role. This can be done on the [**IAM** page](https://console.cloud.google.com/iam-admin/iam) of the Google Cloud console.

3. Make the token available to debug builds of your app without hardcoding it
   in your source code. Treat the token like a credential and keep it out of
   version control. For example, add it to your project's `local.properties`
   file, which isn't checked into version control:

       fpnv.testToken=COPIED_TOKEN_STRING

   Then expose it as a `BuildConfig` field in your module (app-level)
   `build.gradle.kts` file. The following example also reads an
   `FPNV_TEST_TOKEN` environment variable, which is useful on CI servers that
   don't have a `local.properties` file. Release builds get an empty value:

   ```kotlin
   // At the top of the file:
   import java.util.Properties

   val localProperties = Properties().apply {
       rootProject.file("local.properties").takeIf { it.exists() }
           ?.inputStream()?.use { load(it) }
   }
   val fpnvTestToken = System.getenv("FPNV_TEST_TOKEN")?.takeIf { it.isNotEmpty() }
       ?: localProperties.getProperty("fpnv.testToken", "")

   android {
       buildFeatures {
           buildConfig = true
       }
       buildTypes {
           debug {
               buildConfigField("String", "FPNV_TEST_TOKEN", "\"$fpnvTestToken\"")
           }
           release {
               buildConfigField("String", "FPNV_TEST_TOKEN", "\"\"")
           }
       }
   }
   ```
4. In your app, enable a test session once per app process:

   ### Kotlin

   `FirebasePhoneNumberVerification.getInstance()` returns the same
   instance for the default `FirebaseApp` every time you call it, so use
   it for all Firebase PNV calls.

   Call `enableTestSession()` only once per app process. A second call
   throws a `FirebasePhoneNumberVerificationException` with the error code
   `TEST_SESSION_ALREADY_ENABLED`, so don't call it from an `Activity`,
   which can be recreated (for example, when the screen rotates). Instead,
   call it from your `Application` class:

   ```kotlin
   import android.app.Application
   import android.util.Log
   import com.google.firebase.pnv.FirebasePhoneNumberVerification

   class MyApplication : Application() {
       override fun onCreate() {
           super.onCreate()
           if (!BuildConfig.DEBUG) return
           if (BuildConfig.FPNV_TEST_TOKEN.isEmpty()) {
               Log.w("MyApplication", "No Firebase PNV test token; test mode is off.")
               return
           }
           FirebasePhoneNumberVerification.getInstance()
               .enableTestSession(BuildConfig.FPNV_TEST_TOKEN)
       }
   }
   ```

   Register the class in your app manifest:

   ```xml
   <application
       android:name=".MyApplication"
       ... >
   ```

Test tokens have a 7 day TTL; after this period you will need to generate a new
token to enable test sessions. An expired token doesn't cause an error until you
call `getVerifiedPhoneNumber()`. Test tokens work on physical devices and
emulators that have Google Play services, making them ideal for prototyping the
UX in your app. You can also use them for testing in CI/CD if you replace the
token at least every 7 days.

Phone number tokens that your app gets in test mode are signed like production
tokens, but they include the claim `"test_number": true`. Make sure your
production backend rejects tokens with this claim.

## 3. Recommended: Check for Firebase PNV support

To help you determine when to show number entry UI or explainer UI, on app
launch it is recommended to check if the device and its SIM card support
Firebase PNV. This is a pre-check that doesn't require user consent. You can use the
result of this test to decide whether to initiate the Firebase PNV flow or to use an
alternative method of phone number verification, such as SMS.

To check the device for compatibility, call the `getVerificationSupportInfo()`
method. While you have a test session active, this method always returns a list
containing a single supported entry for the test token, without contacting the
Firebase PNV backend. This means you can't exercise your unsupported-device fallback
in test mode. Later, after you productionize your app, this method will return
a result for each SIM in the device.

### Kotlin

```kotlin
val fpnv = FirebasePhoneNumberVerification.getInstance()

val supportInfo: Task<List<VerificationSupportResult>> = fpnv.getVerificationSupportInfo()

// Cache this value for 1 hour to avoid exceeding per-device quota.
val dcp: Task<String> = fpnv.getDigitalCredentialPayload("")

Tasks.whenAllSuccess<Any>(supportInfo, dcp)
    .addOnSuccessListener { results ->
        // Triggered only if BOTH tasks succeed
        val supportInfo = results[0] as List<VerificationSupportResult>
        val dcp = results[1] as String
        if (supportInfo.any { it.isSupported() }) {
            // Both checks passed. Proceed to getVerifiedPhoneNumber
            // (see the next step).
        }
    }
    .addOnFailureListener { exception ->
        // Triggered if AT LEAST ONE task fails. Fallback to SMS
    }
```

> [!CAUTION]
>
> **Known issue:** If a device fails device
> integrity checks, `getVerificationSupportInfo()` will return a
> success but `getVerifiedPhoneNumber()` will fail.
> As a workaround, call `getDigitalCredentialPayload()` in
> addition to `getVerificationSupportInfo()` and check both
> results, as shown above.

## 4. Initiate the verification flow

To initiate the Firebase PNV flow, call the `getVerifiedPhoneNumber()` method. Pass
an `Activity`, because the method displays the consent screen. A `Context` that
isn't an `Activity`, such as your `Application` context, fails with the error
code `ACTIVITY_CONTEXT_REQUIRED`.

### Kotlin

```kotlin
fpnv.getVerifiedPhoneNumber(this@MainActivity)
    .addOnSuccessListener { result ->
        // In test mode, this phone number will have a valid country code,
        // followed by all zeros.
        val phoneNumber = result.getPhoneNumber() // For display only.
        val token = result.getToken()

        // Verification successful. Send token to your backend, which reads
        // the verified phone number from it. (See Next steps.)
    }
    .addOnFailureListener { e ->
        // Handle failures, such as the user declining consent or a network
        // error.
    }
```

The `getVerifiedPhoneNumber()` method carries out the entire phone number
verification flow, including:

- Using the Android Credential Manager to acquire user consent to share their phone number.
- Making the request to the Firebase PNV backend.
- Returning a token containing the verified phone number for the device (in a production app, this is when billing happens).

> [!TIP]
> **Tip:** As a UI refinement, you should display a loading spinner before calling `getVerifiedPhoneNumber`, and dismiss the spinner after the operation completes, either successfully or with an error. Design the loading spinner to be smaller than the consent screen so that it is completely obscured by it when the screen is visible.

## 5. Handle errors

When an Firebase PNV call fails, the exception is a
`FirebasePhoneNumberVerificationException`. Use its `errorCode` to decide what
to do next, for example to fall back to SMS verification when the user declines
consent. See [Handle Firebase PNV errors on Android](https://firebase.google.com/docs/phone-number-verification/android/handle-errors.md.txt) for every error
code, when it occurs, and the recommended action.

## Next steps

- This page details how to integrate with Firebase PNV using the unified,
  single-call API. Calling a single method handles the entire Firebase PNV user
  flow, from obtaining user consent to making the necessary network calls to
  the Firebase PNV backend. By using this method, you reduce the integration steps
  to a single method call.

  This API is recommended for most developers; however, if you have specific
  requirements not met by the library, see the [Customize the Firebase Phone Number Verification
  flow](https://firebase.google.com/docs/phone-number-verification/android/custom-flow) page for information on implementing a custom flow.
- If you use the verified phone number outside the app client, you should pass
  around the token instead of the phone number itself so you can verify its
  integrity when you use it. See [Verify Firebase PNV
  tokens](https://firebase.google.com/docs/phone-number-verification/verify-tokens).

- To sign users in to Firebase Authentication with their verified phone number, see
  [Authenticate with Firebase using Firebase Phone Number Verification](https://firebase.google.com/docs/phone-number-verification/android/sign-in.md.txt).

- For a step-by-step walkthrough that builds a complete sample app, try the
  [Firebase Phone Number Verification codelab](https://firebase.google.com/codelabs/firebase-pnv-android).

- After you have implemented and tested your app's Firebase PNV flow and backend
  integration, you can put your app into production to start getting real
  verified phone numbers. See [Upgrade to production mode](https://firebase.google.com/docs/phone-number-verification/android/production-mode.md.txt).

- For the full API, see the
  [Firebase PNV API reference](https://firebase.google.com/docs/reference/kotlin/com/google/firebase/pnv/package-summary.md.txt).