How to Sign in to Your iOS App with Email/Password Using Firebase Authentication
Firebase is a great and powerful platform which provides lots of features including Cloud Messaging, Cloud Functions and Cloud Firestore, etc. One of the useful features is Firebase Authentication. It allows developers to directly create and manage user accounts without caring about the underlying server codes! Using Firebase Security Rules, you can secure your data, making sure users can only access the data they own.
Firebase provides plenty of authentication methods, including Email/ Password, Google Sign-In, Facebook Sign-In and Sign in with Apple, etc. In this article, we will go through the details and pitfalls of Email/ Password Authentication. Here is the content list:
- Prerequisites
- Signing up
- Signing in
- Logging out
- Forgotten Password Flow
- Updating the User’s Password
- Updating the User’s Email
- Deleting a User Account
- Customising Email Templates
- Some Limitations
Prerequisites (4 steps):
- Create a project with an iOS app using the Firebase Console, and connect your iOS app to the newly created Firebase project with the use of
GoogleService-Info.plist
, which is a file generated during your app registration and containing important information, e.g.PROJECT_ID
,BUNDLE_ID
andAPI_KEY
.
2. Add the Firebase Authentication pod to your Podfile
and run pod install
afterward.
3. Initialise the Firebase configuration in AppDelegate.swift
at the start of the app:
4. Enable Email/Password authentication in the Authentication section in the Firebase Console:
Signing Up
Signing up a new user is as easy as just calling a single function createUser(withEmail: String, password: String, callback: AuthResultCallback)
. AuthResultCallback
returns the authentication result object (AuthResult
) when the account creation succeeds and an error (Error
) when the operation is rejected by the Firebase system.
Here are the possible errors thrown:
AuthErrorCode.operationNotAllowed
— this indicates that theEmail/Password
provider is disabled. You can enable it in the Firebase Console, see step 4 aboveAuthErrorCode.emailAlreadyInUse
— the email address is already in use by another accountAuthErrorCode.invalidEmail
— the email address is badly formatted, e.g.example@!?!?.com
AuthErrorCode.weakPassword
— the password must be 6 characters long or more
If there are no errors, the user is automatically logged in to the newly created account — no need to call the sign-in function. After successfully signing in, you can retrieve the currently signed in user via Auth.auth().currentUser.
Here are two useful snippets for checking the email and password format:
Signing In
You can sign in a user by calling signIn(withEmail: String, password: String, callback: AuthResultCallback)
. If things go wrong, one of the following errors is thrown:
AuthErrorCode.operationNotAllowed
— this indicates that theEmail/Password
sign-in provider is disabled. Enable the provider via the Authentication section of the Firebase Console, see step 4 above.AuthErrorCode.userDisabled
— the user account has been disabled by an administrator.AuthErrorCode.invalidEmail
— the email address provided is malformed, e.g.example@!?!?!?.com
AuthErrorCode.wrongPassword
— the password is invalid or the user does not have a password
* Note that the user can log in to another account without logging out of the current account. To prevent accidentally overwriting existing user information, you should manually check the user status before showing the login page.
Signing Out
The sign out function clears the current user information and token locally. Therefore, it is not an asynchronous function and does not need any callbacks. However, it can also throw an error during the process:
AuthErrorCode.keychainError
— indicates an error occurred when accessing the keychain
Forgotten Password Flow
Firebase would send user a reset password email with a link which directs the user to a reset password webpage. The default email template is multilingual and customisable. Here are the English and Tradition Chinese versions, respectively:
By setting the languageCode
property, you can select which language the email will be sent in to the user. Here is the list of supported languages and some examples:
en
— Englishen_gb
— English (UK)zh_tw
— Traditional Chinesezh_cn
— Simplified Chinese
* Please note that you have to create custom email action handlers to support multilingual email templates after you customise the template content.
Option 1 (Easier) : Using the Firebase Console
Option 2: Programmatically
Call sendPasswordReset(withEmail: String, callback: AuthResultCallback)
to send the user a reset password email. By clicking the link embedded in the email, the user will be directed to the reset password webpage. The default template looks like this:
Here are the exceptions that might be thrown:
AuthErrorCode.userNotFound
— when Firebase cannot find an account with the email address the user specifiedAuthErrorCode.invalidEmail
— the email address is badly formatted, e.g.example@!?!?!?.com
AuthErrorCode.invalidRecipientEmail
— indicates an invalid recipient email was sent in the requestAuthErrorCode.invalidSender
— indicates an invalid sender email is set in the console for this actionAuthErrorCode.invalidMessagePayLoad
— indicates an invalid email template for sending update email
Are you curious what happens if the user has been disabled by the admin? Well, it would NOT throw an exception and the reset password email will be sent! Firebase only throws an error when the user tries to reset a password at the reset password webpage. In my opinion, this is not perfect and would be better for the SDK to throw an exception in this case.
The overall flow of reset password at the webpage:
* Please note that after resetting email address, the original user credentials will be no longer valid and the user must sign in again to renew their token, else all the other functions for updating personal information will throw a
AuthErrorCode.userTokenExpired
.
Updating the User’s Password
Updating the user’s password is straightforward by calling updatePassword(to: String, callback: AuthResultCallback)
function. Please note that the password must consist of at least 6 characters.
Here are the possible errors:
AuthErrorCode.userDisabled
: the user account has been disabled by an administratorAuthErrorCode.weakPassword
— the given password is invalid, i.e. the password should at least consist of six charactersAuthErrorCode.operationNotAllowed
—the given sign-in provider is disabled for this Firebase project. Enable it in the Firebase console, under the sign-in method tab of the Authentication section.AuthErrorCode.requiresRecentLogin
— updating a user’s password is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, re-authenticate the user by invokingreauthenticateWithCredential:completion:
onFIRUser
.AuthErrorCode.userTokenExpired
— the user’s credential is no longer valid, the user must sign in again
Updating the User’s Email
Updating the user’s email is slightly different from updating the user’s password. Nevertheless, it’s just one line of code: updateEmail(to: String, callback: AuthResultCallback)
.
A confirmation email will be sent to the user after the login email has been changed successfully on the Firebase server. The email template is not customisable due to the Firebase policy of spam prevention. Here is an example of the confirmation email:
Possible errors:
AuthErrorCode.emailAlreadyInUse
—
Case 1: the email address is currently in use by another account
Case 2: although the email address is not currently occupied by another account, it was another user’s initial email for sign-upAuthErrorCode.invalidEmail
— the email address is badly formatted, e.g.example@!?!?!?.com
AuthErrorCode.invalidRecipientEmail
— indicates an invalid recipient email was sent in the requestAuthErrorCode.invalidSender
— indicates an invalid sender email is set in the console for this action.AuthErrorCode.invalidMessagePayLoad
— indicates an invalid email template for sending update emailAuthErrorCode.requiresRecentLogin
— updating a user’s password is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, re- authenticate the user by invokingreauthenticateWithCredential:completion:
onFIRUser
.
Deleting a User Account
Deleting a user account is as simple as just calling delete(callback: AuthResultCallback)
function of the current logged in user object. However, there is still one possible failure case:
AuthErrorCode.operationNotAllowed
— this indicates that theEmail/Password
sign-in provider is disabled. Enable the provider via the Authentication section of the Firebase Console, see step 4 above.AuthErrorCode.requiresRecentLogin
— Updating a user’s password is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, re-authenticate the user by invokingreauthenticateWithCredential:completion:
onFIRUser
.
* Please note that a deleted account is not recoverable and developers should make sure their users are aware of the consequences before performing this operation.
Customising Email templates
So far, we’ve covered two kinds of emails: the reset password email and the update email address email. However, only the reset password email template can be edited by the admin. Admins cannot make any changes to the update email address template due to the Firebase policy to prevent spam.
You can customise the password reset email template in the following page:
The original password reset email template is very simple and contains three Firebase tags:
%LINK%
(required): link where users can reset their password%APP_NAME%
: your app’s public name%EMAIL%
: the user’s email address
Using a little bit of HTML and some Firebase tags, we can customise the layout and content. See the example below:
Limitations
To prevent the abuse of account creation, Firebase limits the number of accounts that can be created from the same IP address to 100 accounts per hour. This might not be convenient during development and QA stage. The good news is that you can change this quota temporarily from the Firebase console.
。Max number of sign-ups per IP address per hour: 100
。Schedule time: Within the current year (365 days)
。Max day range: 7 days
The settings can take up to an hour to take effect.
Summary
- Firebase Authentication provides many sign-up options and one of them is email/password.
- The Firebase SDK provides functions for signing up, signing in, signing out, updating email and password, resetting password and deleting account.
- Only non-occupied email addresses and non-initial sign-up email addresses can be used for updating the login email address.
- Default reset password email can be sent to user with different languages by calling a function
setLanguageCode(locale: String)
. - Only reset password template can be customised in Firebase system. After customising the reset password email template, custom email action handlers must be implemented in order to support multilingual feature.
- Only 100 new accounts can be created per hour from the same IP. It can be temporarily configured up to 1000 new accounts with max duration of 7 days.
Resources
Please follow me at Twitter@myrick_chow for more information. Thank you for reading this article. Have a nice day! 😄