How to Sign in to Your iOS App with Email/Password Using Firebase Authentication

Myrick Chow
Firebase Developers
9 min readFeb 16, 2020

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:

  1. Prerequisites
  2. Signing up
  3. Signing in
  4. Logging out
  5. Forgotten Password Flow
  6. Updating the User’s Password
  7. Updating the User’s Email
  8. Deleting a User Account
  9. Customising Email Templates
  10. Some Limitations

Prerequisites (4 steps):

  1. 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 and API_KEY .
GoogleService-Info.plist must be added to your target

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:

Steps for enabling Email/ Password feature

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:

  1. AuthErrorCode.operationNotAllowed — this indicates that the Email/Password provider is disabled. You can enable it in the Firebase Console, see step 4 above
  2. AuthErrorCode.emailAlreadyInUse — the email address is already in use by another account
  3. AuthErrorCode.invalidEmailthe email address is badly formatted, e.g. example@!?!?.com
  4. 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:

  1. AuthErrorCode.operationNotAllowed — this indicates that the Email/Password sign-in provider is disabled. Enable the provider via the Authentication section of the Firebase Console, see step 4 above.
  2. AuthErrorCode.userDisabled — the user account has been disabled by an administrator.
  3. AuthErrorCode.invalidEmail — the email address provided is malformed, e.g. example@!?!?!?.com
  4. 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:

  1. 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:

  1. en — English
  2. en_gb — English (UK)
  3. zh_tw — Traditional Chinese
  4. zh_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

Steps for sending reset password email to user

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:

Default email template for resetting password

Here are the exceptions that might be thrown:

  1. AuthErrorCode.userNotFound — when Firebase cannot find an account with the email address the user specified
  2. AuthErrorCode.invalidEmail — the email address is badly formatted, e.g. example@!?!?!?.com
  3. AuthErrorCode.invalidRecipientEmail — indicates an invalid recipient email was sent in the request
  4. AuthErrorCode.invalidSender — indicates an invalid sender email is set in the console for this action
  5. AuthErrorCode.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:

  1. AuthErrorCode.userDisabled: the user account has been disabled by an administrator
  2. AuthErrorCode.weakPassword — the given password is invalid, i.e. the password should at least consist of six characters
  3. AuthErrorCode.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.
  4. 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 invoking reauthenticateWithCredential:completion: on FIRUser.
  5. 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:

  1. 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-up
  2. AuthErrorCode.invalidEmail — the email address is badly formatted, e.g. example@!?!?!?.com
  3. AuthErrorCode.invalidRecipientEmail — indicates an invalid recipient email was sent in the request
  4. AuthErrorCode.invalidSender — indicates an invalid sender email is set in the console for this action.
  5. AuthErrorCode.invalidMessagePayLoad — indicates an invalid email template for sending update email
  6. 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 invoking reauthenticateWithCredential:completion: on FIRUser.

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:

  1. AuthErrorCode.operationNotAllowed — this indicates that the Email/Password sign-in provider is disabled. Enable the provider via the Authentication section of the Firebase Console, see step 4 above.
  2. 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 invoking reauthenticateWithCredential:completion: on FIRUser.

* 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:

Steps for customising password reset email template

The original password reset email template is very simple and contains three Firebase tags:

  1. %LINK% (required): link where users can reset their password
  2. %APP_NAME%: your app’s public name
  3. %EMAIL%: the user’s email address
Email template example for resetting password

Using a little bit of HTML and some Firebase tags, we can customise the layout and content. See the example below:

Example of customised email template

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.

Steps for configuring the sign-up quota (per IP in an hour)
Sign-up Quota configuration setting dialog

Summary

  1. Firebase Authentication provides many sign-up options and one of them is email/password.
  2. The Firebase SDK provides functions for signing up, signing in, signing out, updating email and password, resetting password and deleting account.
  3. Only non-occupied email addresses and non-initial sign-up email addresses can be used for updating the login email address.
  4. Default reset password email can be sent to user with different languages by calling a function setLanguageCode(locale: String) .
  5. 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.
  6. 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.

--

--

Myrick Chow
Firebase Developers

Mobile Lead @REAL Messenger Inc. https://real.co Focus on Android & iOS Native programming.