Authenticate with Firebase on iOS using a Phone Number

You can use Firebase Authentication to sign in a user by sending an SMS message
to the user's phone. The user signs in using a one-time code contained in the
SMS message.

The easiest way to add phone number sign-in to your app is to use
FirebaseUI,
which includes a drop-in sign-in widget that implements sign-in flows for phone
number sign-in, as well as password-based and federated sign-in. This document
describes how to implement a phone number sign-in flow using the Firebase SDK.

Phone numbers that end users provide for authentication will be sent and stored
by Google to improve our spam and abuse prevention across Google services,
including but not limited to Firebase. Developers should ensure they have
appropriate end-user consent prior to using the Firebase Authentication phone number
sign-in service.

Before you begin

If you haven't yet connected your app to your Firebase project, do so from
the Firebase console.

Security concerns

Authentication using only a phone number, while convenient, is less secure
than the other available methods, because possession of a phone number
can be easily transferred between users. Also, on devices with multiple user
profiles, any user that can receive SMS messages can sign in to an account using
the device's phone number.

If you use phone number based sign-in in your app, you should offer it
alongside more secure sign-in methods, and inform users of the security
tradeoffs of using phone number sign-in.

Enable Phone Number sign-in for your Firebase project

To sign in users by SMS, you must first enable the Phone Number sign-in
method for your Firebase project:

Firebase's phone number sign-in request quota is high enough that most apps
won't be affected. However, if you need to sign in a very high volume of users
with phone authentication, you might need to upgrade your pricing plan. See
the pricing page.

Enable app verification

To use phone number authentication, Firebase must be able to verify that
phone number sign-in requests are coming from your app. There are two ways
Firebase Authentication accomplishes this:

Silent APNs notifications: When you sign in a user with their
phone number for the first time on a device, Firebase Authentication sends a
token to the device using a silent push notification. If your app
successfully receives the notification from Firebase, phone number
sign-in can proceed.

For iOS 8.0 and newer, silent notifications do not require explicit
user consent and is therefore unaffected by a user declining to receive
APNs notifications in the app. Thus, the app does not need to request user
permission to receive push notifications when implementing Firebase phone
number auth.

reCAPTCHA verification: In the event that sending or receiving
a silent push notification is not possible, such as when the user has
disabled background refresh for your app, or when testing your app on an
iOS simulator, Firebase Authentication uses reCAPTCHA verification to complete
the phone sign-in flow. The reCAPTCHA challenge can often be completed
without the user having to solve anything.

When silent push notifications are properly configured, only a very small
percentage of users will experience the reCAPTCHA flow. Nonetheless, you should
ensure that phone number sign-in functions correctly whether or not silent push
notifications are available.

To ensure that both scenarios are working correctly, test
your app on a physical iOS device with background app refresh both enabled and
disabled. When background app refresh is disabled, you should be able to
successfully sign in after completing the reCAPTCHA challenge. You can also
test the reCAPTCHA flow by running your app on an iOS simulator, which always
uses the reCAPTCHA flow.

Browse to the location where you saved your key, select it, and click
Open. Add the key ID for the key (available in Certificates,
Identifiers & Profiles in the
Apple Developer Member Center) and click
Upload.

If you already have an APNs certificate, you can upload the certificate
instead.

Set up reCAPTCHA verification

To enable the Firebase SDK to use reCAPTCHA verification:

Add custom URL schemes to your Xcode project:

Open your project configuration: double-click the project name in the
left tree view. Select your app from the TARGETS section, then
select the Info tab, and expand the URL Types section.

Click the + button, and add a URL scheme for your reversed
client ID. To find this value, open the
GoogleService-Info.plist configuration file, and look for
the REVERSED_CLIENT_ID key. Copy the value of that key,
and paste it into the URL
Schemes box on the configuration page. Leave the other fields blank.

When completed, your config should look something similar to the
following (but with your application-specific values):

Optional: If you want to customize the way your app presents the
SFSafariViewController or UIWebView when
displaying the reCAPTCHA to the user, create a custom class that conforms
to the FIRAuthUIDelegate protocol, and pass it to
verifyPhoneNumber:UIDelegate:completion:.

Send a verification code to the user's phone

To initiate phone number sign-in, present the user an interface that prompts
them to provide their phone number, and then call
verifyPhoneNumber:UIDelegate:completion: to request that Firebase
send an authentication code to the user's phone by SMS:

Get the user's phone number.

Legal requirements vary, but as a best practice
and to set expectations for your users, you should inform them that if they use
phone sign-in, they might receive an SMS message for verification and standard
rates apply.

Call verifyPhoneNumber:UIDelegate:completion:, passing to it
the user's phone number.

Swift

PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { (verificationID, error) in
if let error = error {
self.showMessagePrompt(error.localizedDescription)
return
}
// Sign in using the verificationID and the code sent to the user
// ...
}

When you call verifyPhoneNumber:UIDelegate:completion:,
Firebase sends a silent push notification to your app, or issues a
reCAPTCHA challenge to the user. After your app receives the
notification or the user completes the reCAPTCHA challenge, Firebase
sends an SMS message containing an authentication code to the
specified phone number and passes a verification ID to your completion
function. You will need both the verification code and the verification
ID to sign in the user.

The SMS message sent by Firebase can also be localized by specifying the
auth language via the languageCode property on your Auth
instance.

Swift

// Change language code to french.
Auth.auth().languageCode = "fr";

Objective-C

Save the verification ID and restore it when your app loads. By doing so,
you can ensure that you still have a valid verification ID if your app is
terminated before the user completes the sign-in flow (for example, while
switching to the SMS app).

You can persist the verification ID any way you want. A simple way is to
save the verification ID with the NSUserDefaults object:

Swift

Objective-C

If the call to verifyPhoneNumber:UIDelegate:completion:
succeeds, you can prompt the user to type the verification code when they
receive it in the SMS message.

To prevent abuse, Firebase enforces a limit on the number of
SMS messages that can be sent to a single phone number within a period of time.
If you exceed this limit, phone number verification requests might be throttled.
If you encounter this issue during development, use a different phone number for
testing, or try the request again later.

Sign in the user with the verification code

After the user provides your app with the verification code from the SMS
message, sign the user in by creating a FIRPhoneAuthCredential
object from the verification code and verification ID and passing that object
to signInWithCredential:completion:.

Get the verification code from the user.

Create a FIRPhoneAuthCredential object from the verification
code and verification ID.

Test with whitelisted phone numbers

You can whitelist phone numbers for development via the Firebase console. Whitelisting phone
numbers provides these benefits:

Test phone number authentication without consuming your usage quota.

Test phone number authentication without sending an actual SMS message.

Run consecutive tests with the same phone number without getting throttled. This
minimizes the risk of rejection during App store review process if the reviewer happens to use
the same phone number for testing.

Test readily in development environments without any additional effort, such as
the ability to develop in an iOS simulator or an Android emulator without Google Play Services.

Write integration tests without being blocked by security checks normally applied
on real phone numbers in a production environment.

Phone numbers to whitelist must meet these requirements:

Make sure you use fictional numbers that do not already exist.
Firebase Authentication does not allow you to whitelist existing phone numbers used by real users.
One option is to use 555 prefixed numbers as US test phone numbers, for example:
+1 650-555-3434

Phone numbers have to be correctly formatted for length and other
constraints. They will still go through the same validation as a real user's phone number.

You can add up to 10 phone numbers for development.

Use test phone numbers/codes that are hard to guess and change
those frequently.

Whitelist phone numbers and verification codes

In the Sign in method tab, enable the Phone provider if you haven't already.

Open the Phone numbers for testing accordion menu.

Provide the phone number you want to test, for example: +1 650-555-3434.

Provide the 6-digit verification code for that specific number, for example: 654321.

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 whitelisted 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 whitelisted 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.

Because the ID token for the whitelisted phone number has
the same signature as a real phone number user, it is important to store these numbers
securely and to continuously recycle them.

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.

Make sure app verification is not disabled for production apps and
that no whitelisted phone numbers are hardcoded in your production app.

On iOS, the appVerificationDisabledForTesting setting has to be set to
TRUE before calling verifyPhoneNumber. This is processed without requiring
any APNs token or sending silent push notifications in the background, making it easier to test
in a simulator. This also disables the reCAPTCHA fallback flow.

Note that when app verification is disabled, using a non-whitelisted phone number will
fail to complete sign in. Only whitelisted phone numbers can be used with this API.

If you prefer not to use swizzling, you can disable it by adding the flag
FirebaseAppDelegateProxyEnabled to your app's Info.plist file and
setting it to NO. Note that setting this flag to NO
also disables swizzling for other Firebase products, including
Firebase Cloud Messaging.

If you disable swizzling, you must explicitly pass the APNs device token,
push notifications, and the custom scheme redirect URL to Firebase Authentication.

To obtain the APNs device token, implement the
application:didRegisterForRemoteNotificationsWithDeviceToken:
method, and in it, pass the device token to FIRAuth's
setAPNSToken:type: method.

To handle the custom scheme redirect URL, implement the
application:openURL:sourceApplication:annotation: method for
devices running iOS 8 and older, and the
application:openURL:options: method for devices running iOS 9 and
newer, and in them, pass the URL to FIRAuth's
canHandleURL method.

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
FIRUser 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.