This module requires that the @react-native-firebase/app module is already setup and installed. To install the "app" module, view the
Getting Started documentation.
# Install & setup the app module
yarn add @react-native-firebase/app
# Install the phone-number-verification module
yarn add @react-native-firebase/phone-number-verificationAndroid only - This module is only available on Android. The Firebase Phone Number Verification SDK does not support iOS or web platforms. Calling any method on a non-Android platform will throw an error.
| Platforms | Android only |
| New Architecture | Required from v26. See Migrating to v26. |
Firebase Phone Number Verification provides carrier-level phone number verification on Android devices without requiring SMS codes. It verifies the user's phone number directly through the device's SIM card and carrier network, providing a seamless and secure verification experience.
To learn more, visit the Firebase Phone Number Verification documentation.
Key capabilities:
- Carrier-level verification: Verifies phone numbers directly with the mobile carrier, without SMS.
- Support detection: Check whether the device and carrier support phone number verification before attempting it. This does not require user consent.
- Verified phone number: Retrieve the device's verified phone number as a JWT token containing the phone number, timestamps, nonce, and claims. This will present a consent dialog to the user.
- Digital Credential API: Supports the Android Digital Credential API for custom verification flows.
Phone Number Verification depends on carrier cooperation. Not all carriers or regions are supported. Before relying on Phone Number Verification, always call getVerificationSupportInfo() to check support. If a SIM slot returns reason: 'INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED', that carrier does not participate in Phone Number Verification and you should fall back to another verification method (e.g. Firebase Auth SMS).
Common reasons verification may be unsupported:
| Reason | Meaning |
|---|---|
CAPABLE | The SIM's carrier supports Phone Number Verification. |
INCAPABLE_DUE_TO_CARRIER_UNSUPPORTED | The carrier does not participate in Phone Number Verification. |
INCAPABLE_DUE_TO_ANDROID_VERSION | The device's Android version is too old. |
INCAPABLE_DUE_TO_SIM_STATE | No SIM inserted, or SIM is in an unusable state. |
CAPABILITY_STATUS_UNSPECIFIED | The SDK could not determine the status. |
Before attempting verification, check if the device's SIM card(s) support phone number verification. This call does not require user consent and can be called freely:
import { getVerificationSupportInfo } from '@react-native-firebase/phone-number-verification';
const supportInfo = await getVerificationSupportInfo();
for (const info of supportInfo) {
console.log(`SIM slot ${info.simSlot}:`);
console.log(' Supported:', info.isSupported);
console.log(' Carrier ID:', info.carrierId);
console.log(' Reason:', info.reason);
}The method returns an array with one entry per SIM slot. Each entry includes:
isSupported— whether Phone Number Verification is available for this SIM.simSlot— the SIM slot index (0-based).carrierId— the carrier identifier string.reason— aVerificationSupportStatusstring explaining why the SIM is or isn't supported.
On dual-SIM devices, you can query a specific SIM slot by passing the slot index:
import { getVerificationSupportInfo } from '@react-native-firebase/phone-number-verification';
const supportInfo = await getVerificationSupportInfo(0); // SIM slot 0If Phone Number Verification is not supported, fall back to an alternative verification method:
import { Platform } from 'react-native';
import {
getVerificationSupportInfo,
getVerifiedPhoneNumber,
} from '@react-native-firebase/phone-number-verification';
async function verifyPhoneNumber() {
if (Platform.OS !== 'android') {
// Use SMS-based verification on non-Android platforms
return verifySms();
}
const supportInfo = await getVerificationSupportInfo();
const supported = supportInfo.some(info => info.isSupported);
if (supported) {
try {
return await getVerifiedPhoneNumber();
} catch (error) {
// Fall back to SMS on failure
return verifySms();
}
}
// Carrier or device doesn't support Phone Number Verification
return verifySms();
}To initiate the full verification flow, call getVerifiedPhoneNumber(). This will present a consent dialog to the user asking permission to share their phone number. Your app should prepare the user for this consent screen before calling the method — for example, by explaining why their phone number is needed.
For guidance on handling user consent, see the Firebase Phone Number Verification getting started guide.
import { getVerifiedPhoneNumber } from '@react-native-firebase/phone-number-verification';
try {
const result = await getVerifiedPhoneNumber();
console.log('Phone number:', result.phoneNumber);
console.log('Token:', result.token);
console.log('Expires at:', new Date(result.expirationTimestamp * 1000));
console.log('Issued at:', new Date(result.issuedAtTimestamp * 1000));
console.log('Nonce:', result.nonce);
console.log('Claims:', result.claims);
} catch (error) {
console.error('Verification failed:', error.code, error.message);
}The returned result includes:
phoneNumber— the verified phone number in E.164 format.token— the raw JWT token string for server-side validation.expirationTimestamp— token expiration as Unix epoch seconds.issuedAtTimestamp— token issued-at time as Unix epoch seconds.nonce— the nonce from the JWT payload, ornull.claims— all JWT claims as a key-value map, ornull.
For advanced use cases, you can use the Digital Credential API flow:
import {
getDigitalCredentialPayload,
exchangeCredentialResponseForPhoneNumber,
} from '@react-native-firebase/phone-number-verification';
// Step 1: Get the credential payload
const payload = await getDigitalCredentialPayload('your-unique-nonce');
// Step 2: Use the payload with Android Credential Manager
// ... (pass payload to CredentialManager API)
// Step 3: Exchange the response for a verified phone number
const result = await exchangeCredentialResponseForPhoneNumber(credentialResponse);
console.log('Phone number:', result.phoneNumber);
console.log('Expires at:', new Date(result.expirationTimestamp * 1000));All methods reject with structured error codes from the Firebase Phone Number Verification SDK. The error.code property contains one of these values:
| Error Code | Meaning |
|---|---|
pnv/carrier-not-supported | The SIM's carrier does not support Phone Number Verification. |
pnv/invalid-digital-credential-response | The Digital Credential API response was invalid. |
pnv/integrity-check-failed | Device integrity check failed. |
pnv/preflight-check-failed | Server-side preflight check failed. |
pnv/unsupported-operation | The API call is not supported with the given parameters. |
pnv/credential-manager-error | Android Credential Manager failed unexpectedly. |
pnv/invalid-test-number-id | Test number IDs are empty, expired, or duplicated. |
pnv/test-session-already-enabled | enableTestSession was called more than once. |
pnv/activity-context-required | An Activity context is required (app may be in the background). |
import {
getVerifiedPhoneNumber,
PnvErrorCode,
type PnvError,
} from '@react-native-firebase/phone-number-verification';
try {
const result = await getVerifiedPhoneNumber();
} catch (error) {
const pnvError = error as PnvError;
switch (pnvError.code) {
case PnvErrorCode.CARRIER_NOT_SUPPORTED:
// Fall back to SMS verification
break;
case PnvErrorCode.ACTIVITY_CONTEXT_REQUIRED:
// Retry when app is in foreground
break;
default:
console.error('Phone Number Verification error:', pnvError.code, pnvError.message);
}
}To test without a real SIM card and carrier, use Firebase's test mode. This requires setup in the Firebase Console:
- Generate a test token: In the Firebase Console, navigate to Phone Number Verification and generate a test token. Test tokens have a 7-day Time-To-Live.
- Identity and Access Management permissions: Ensure the service account has the required
firebasepnv.testSessions.createpermission. - Google system services beta: On the test device, enroll the Google system services app into the beta channel via Google Play.
- Call
enableTestSessiononce: Pass the token before any verification calls. This must be called only once per app instance — calling it again will reject withpnv/test-session-already-enabled.
import {
enableTestSession,
getVerifiedPhoneNumber,
} from '@react-native-firebase/phone-number-verification';
// Call once at app startup for testing
await enableTestSession('your-test-token-from-firebase-console');
// Now verification calls return test data
// Phone numbers in test mode follow the format: valid country code + all zeros
const result = await getVerifiedPhoneNumber();
console.log('Test phone number:', result.phoneNumber);This module is Android-only. On non-Android platforms, all methods throw an error with the message "Firebase Phone Number Verification is only supported on Android." You can guard against this using Platform.OS:
import { Platform } from 'react-native';
import { getVerificationSupportInfo } from '@react-native-firebase/phone-number-verification';
if (Platform.OS === 'android') {
const supportInfo = await getVerificationSupportInfo();
// ...
}
Core / App