Firebase Authentication
Firebase Phone Number Auth in iOS
Firebase Authentication is one of the SDK provided by Google for authenticating a user’s identity. Firebase provides a list of authentication methods, such as Google Sign-In, Sign in with Apple, Email and password authentication, Phone Number authentication, and more.
Phone number authentication is a common way for logging in to a mobile app. When signing in using Phone Number authentication, Firebase sends an SMS message with a 6-digit one-time code to the user’s phone. The user then has to type this code into an input field in the app they want to sing in to. The app then has to send this code with a generated verification ID back to Firebase for verification.
Moreover, Firebase uses silent push notifications and reCAPTCHA to prevent bots spamming the system. Phone Number authentication is secure and easy to setup. Let’s dive into the details!
Overview of Phone Number Authentication
To prevent malicious actors from abusing the authentication system, Firebase Authentication SDK uses a couple of different strategies to verify the request is coming from a real user. Firebase has a generous limit of 10k free verifications, after which each additional successful verification will cost USD 0.01 or USD 0.06 (depending on the country the user is in). You can calculate the cost using this calculator.
Here are the two methods:
1. Silent APNs notifications
These are notifications that do not show up as a notification pop up. Since they don’t require the user’s permission, users won’t even notice your app received a silent notification. By sending a silent notification with a token, Firebase can establish that the sign-in request was actually started on the user’s device.
2. reCAPTCHA
In some cases, it is possible that a device cannot receive silent APNs notification. For example, if the user explicitly disabled the Background App Refresh feature on the app’s preferences page, if the APNs certificate has expired, or excessive APNs have been delivered to the system. In these cases, Firebase uses reCAPTCHA to verify that the user is not a robot.
iOS doesn’t guarantee their delivery. The system may throttle the delivery of background notifications if the total number becomes excessive. The number of background notifications allowed by the system depends on current conditions, but don’t try to send more than two or three per hour.
Reference: Apple Official Documentation — Pushing Background Updates to Your App
If you want to know more about Background App Refresh, check out the following articles:
Implementing Phone Number Auth in 9 Steps
Step 1) Set up a Firebase project with an iOS app
Follow this official guide on setting up a Firebase project. A GoogleService-Info.plist
will be finally generated, which contains all the keys and information for communicating with Firebase. Remember to configure the Firebase SDK at the start of the app:
Step 2) Add Firebase Authentication to your project
Add Firebase Authentication to your Podfile
and run pod install
to install it:
Step 3) Enable Phone Number Authentication in the Firebase Console
Step 4) Set up APNs — Generate Push certificate on the Apple Developer Console
As mentioned before, Firebase SDK uses silent APNs to send token to the user’s device for verifying the origin of the SMS request. Therefore, it is necessary to link your Firebase project with the Apple Push Notification Server with the APNs certificates. You can generate them on the Apple Developer Console with the following steps:
Step 5) Set up APNs — Upload to the Firebase Console
After downloading APNs certificates from the Apple Developer Console, import them to Keychain Access and export the private key with a secured password.
Upload the exported .p12
file to the Firebase Console:
Step 6) Add the Push Notifications capability to your app’s entitlements
Step 7) Add a custom URL Scheme to the Xcode target
Add the REVERSED_CLIENT_ID
value to the “URL Schemes” field at the Info tab.
Step 8) Request a One-Time Password with a phone number
The above code calls verifyPhoneNumber
to verify the phone number provided by the user. The user should receive a confirmation SMS within a couple of seconds. iOS can automatically detect incoming SMS messages and retrieve the authentication code from the message. The verification code is then shown in the keyboard accessory bar when the passcode verification textfield is focussed, as you can see in the GIF above.
However, I’d like to point out a few things:
- The phone number style must be prefixed with area code (e.g. Hong Kong +852 & the USA +1). Here is a full list of area code. The SDK will throw an exception when the phone number doesn’t match this format.
- The
uiDelegate
param used inverifyPhoneNumber:UIDelegate:completion:
isnil
which means that the system will useSFSafariViewController
orUIWebView
to run the reCAPTCHA flow. If you’d like to have more control over this flow, you can specify a customisedUIViewController
which conformsFIRAuthUIDelegate.
- The
verificationID
has to be saved for creatingPhoneAuthProvider
in the next step. In official documentation, it is recommended to save it inUserDefault
.
Step 9) Sign in with PhoneAuthProvider
In the final step, we need to request an authentication credential from the Phone Number authentication provider by passing in the verificationID
and the one-time passcode received by the user.
We can then use this credential to sign in using Auth.auth().signIn(with: credential)
. After successfully signing in, we can retrieve the signed-in user by calling Auth.auth().currentUser
.
Debugging the SMS flow
To prevent abuse, Firebase set a limit to the number of SMS request made by a single device in a certain period of time. In my experience, no more than 10 SMS requests are allowed to be made within 30 mins.
Therefore, it is recommended to set up a phone number for testing (see above). You can register up to 10 phone numbers for testing. It is useful not only for internal testing or UAT but also for App Store and Google Play Store review, which probably needs to test your login feature multiple times!
Using a test phone number doesn’t require Firebase to send you an SMS and therefore does not affect the monthly free quota on Phone Authentication. Instead, you can just type in the verification code you defined when registering the test phone number.
Test phone numbers should not be real phone numbers. You can either try with several random phone number or “555” prefixed numbers as US test phone numbers, for example: +1 650–555–3434.
Logout
Logging out is a simple one-liner, see above.
Pricing
According to official documentation on 21st August 2020, there are 10,000 free usage for each project every month. Extra successful verification costs from USD$0.01 to USD$0.06.
Discussion
- The phone numbers used for authentication are actually sent and stored by Google for certain services, including improving Google’s spam and abuse prevention systems. It is necessary to inform users about this background information and get their consent before providing the phone number authentication service.
2. Keep in mind that phone numbers might be transferred to another person when the owner terminates their phone plan. Sensitive information can probably be disclosed to new user of that phone number.
Summary
Firebase provides an easy-to-use Phone Number Authentication SDK to sign-in with phone number and one-time passcode.
- Firebase uses either silent push notification with a token or reCAPTCHA to ensure that SMS request are made from the user’s device and not from a malicious bot.
- APNs certificates must be added to Firebase to enable the silent push notification. Failing that, reCAPTCHA will be used instead.
- In order for reCAPTHA to work, the
REVERSED_CLIENT_ID
has to be added to theURL Schemes
of the app project settings. - Phone numbers should be prefixed with an area code.
- Phone numbers used for testing should not be a real phone number, as they will be used for internal testing, UAT and app submission review.
- Phone number information is shared with Google for further improvement of Google services.
- Phone numbers are potentially transferrable from one person to another. Determine if phone number is secure enough for your own case.