Connect your app to the Authentication Emulator

Before using the Authentication emulator with you app, make sure that you understand the overall Firebase Local Emulator Suite workflow, and that you install and configure the Local Emulator Suite and review its CLI commands.

This topic assumes you are already familiar with developing Firebase Authentication solutions for production. If needed, review the documentation for your combination of platform and authentication technique.

What can I do with the Authentication emulator?

The Authentication emulator provides high-fidelity local emulation of Firebase Authentication services, providing much of the functionality found in production Firebase Authentication. Paired with the Apple platforms, Android and Web Firebase SDKs, the emulator lets you:

  • Create, update and manage emulated user accounts for testing email/password, phone number/SMS, SMS multi-factor, and third-party (e.g. Google) identity provider authentication
  • View and edit emulated users
  • Prototype custom token authentication systems
  • Check authentication-related messages in the Emulator UI Logs tab.

Choose a Firebase project

The Firebase Local Emulator Suite emulates products for a single Firebase project.

To select the project to use, before you start the emulators, in the CLI run firebase use in your working directory. Or, you can pass the --project flag to each emulator command.

Local Emulator Suite supports emulation of real Firebase projects and demo projects.

Project type Features Use with emulators
Real

A real Firebase project is one you created and configured (most likely via the Firebase console).

Real projects have live resources, like database instances, storage buckets, functions, or any other resource you set up for that Firebase project.

When working with real Firebase projects, you can run emulators for any or all of the supported products.

For any products you are not emulating, your apps and code will interact with the live resource (database instance, storage bucket, function, etc.).

Demo

A demo Firebase project has no real Firebase configuration and no live resources. These projects are usually accessed via codelabs or other tutorials.

Project IDs for demo projects have the demo- prefix.

When working with demo Firebase projects, your apps and code interact with emulators only. If your app attempts to interact with a resource for which an emulator isn't running, that code will fail.

We recommend you use demo projects wherever possible. Benefits include:

  • Easier setup, since you can run the emulators without ever creating a Firebase project
  • Stronger safety, since if your code accidentally invokes non-emulated (production) resources, there is no chance of data change, usage and billing
  • Better offline support, since there is no need to access the internet to download your SDK configuration.

Instrument your app to talk to the emulator

Android, iOS, and web SDKs

Set up your in-app configuration or test classes to interact with the Authentication emulator as follows.

Kotlin
Firebase.auth.useEmulator("10.0.2.2", 9099)
Java
FirebaseAuth.getInstance().useEmulator("10.0.2.2", 9099);
Swift
Auth.auth().useEmulator(withHost:"127.0.0.1", port:9099)

Web

import { getAuth, connectAuthEmulator } from "firebase/auth";

const auth = getAuth();
connectAuthEmulator(auth, "http://127.0.0.1:9099");

Web

const auth = firebase.auth();
auth.useEmulator("http://127.0.0.1:9099");

No additional setup is needed to prototype and test interactions between Authentication and Cloud Functions or Firebase Security Rules for Cloud Firestore or Realtime Database. When the Authentication emulator is configured and other emulators are running, they automatically work together.

Admin SDKs

The Firebase Admin SDKs automatically connect to the Authentication emulator when the FIREBASE_AUTH_EMULATOR_HOST environment variable is set.

export FIREBASE_AUTH_EMULATOR_HOST="127.0.0.1:9099"

Note that the Cloud Functions emulator is automatically aware of the Authentication emulator so you can skip this step when testing integrations between Cloud Functions and Authentication emulators. The environment variable will be automatically set for the Admin SDK in Cloud Functions.

With the environment variable set, Firebase Admin SDKs will accept unsigned ID Tokens and session cookies issued by the Authentication emulator (via verifyIdToken and createSessionCookie methods respectively) to facilitate local development and testing. Please make sure not to set the environment variable in production.

If you want your Admin SDK code to connect to a shared emulator running in another environment, you will need to specify the the same project ID you set using the Firebase CLI. You can pass a project ID to initializeApp directly or set the GCLOUD_PROJECT environment variable.

Node.js Admin SDK
admin.initializeApp({ projectId: "your-project-id" });
Environment Variable
export GCLOUD_PROJECT="your-project-id"

ID Tokens

For security reasons, the Authentication emulator issues unsigned ID tokens, which are only accepted by other Firebase emulators, or the Firebase Admin SDK when configured. These tokens will be rejected by production Firebase services or Firebase Admin SDK running in production mode (e.g. the default behavior without the setup steps described above).

Start the emulator

You can use the Authentication emulator interactively via the Emulator Suite UI and non-interactively through its local REST interface. The following sections cover interactive and non-interactive use cases.

To start the Authentication emulator, its REST interface, and the Emulator Suite UI, execute:

firebase emulators:start

For anonymous authentication, your app can exercise the sign-in logic for your platform (iOS, Android, web).

For email/password authentication, you can start prototyping by adding user accounts to the Authentication emulator from your app using Authentication SDK methods, or by using the Emulator Suite UI.

  1. In the Emulator Suite UI, click the Authentication tab.
  2. Click the Add user button.
  3. Follow the user account creation wizard, filling in the email authentication fields.

With a test user created, your app can sign the user in and out with SDK logic for your platform (iOS, Android, web).

For testing email verification/sign-in with email link flows, the emulator prints a URL to the terminal at which firebase emulators:start was executed.

i  To verify the email address customer@ex.com, follow this link:
http://127.0.0.1:9099/emulator/action?mode=verifyEmail&lang=en&oobCode=XYZ123&apiKey=fake-api-key

Paste the link into your browser to simulate the verification event, and check whether verification succeeded.

{
  "authEmulator": {
    "success": "The email has been successfully verified.",
    "email": "customer@example.com"
  }
}

For testing password resets, the emulator prints a similar URL, including a newPassword parameter (which you may change as needed), to the terminal.

http://127.0.0.1:9099/emulator/action?mode=resetPassword&oobCode=XYZ!23&apiKey=fake-api-key&newPassword=YOUR_NEW_PASSWORD

Non-interactive testing

Instead of using the Emulator Suite UI or client code to manage email/password user accounts, you can write test setup scripts that call REST APIs to create and delete user accounts and fetch out-of-band email verification codes to populate the emulator email verification URL. This keeps platform and test code separate and lets you test non-interactively.

For non-interactive email and password test flows, the typical sequence is as follows.

  1. Create users with the Authentication signUp REST endpoint.
  2. Sign in users using the emails and passwords to perform tests.
  3. If applicable to your tests, fetch available out-of-band email verification codes from the emulator-specific REST endpoint.
  4. Flush user records with the emulator-specific REST endpoint for clearing data.

Emulated phone/SMS authentication

For phone authentication, the Auth emulator does not support:

  • reCAPTCHA and APN flows. Once configured to interact with the emulator, client SDKs disable these verification methods in a way similar to that described for integration testing (iOS, Android, web).
  • Test phone numbers with codes preconfigured in the Firebase console.

Otherwise, in terms of client code, the phone/SMS authentication flow is identical to that described for production (iOS, Android, web).

Using the Emulator Suite UI:

  1. In the Emulator Suite UI, click the Authentication tab.
  2. Click the Add user button.
  3. Follow the user account creation wizard, filling in the phone authentication fields.

However, for phone authentication flows, the emulator will NOT trigger delivery of any text messages, since contacting a carrier is out of scope and not friendly for local testing! Instead, the emulator prints out the code that would have been sent via SMS to the same terminal at which you ran firebase emulators:start; input this code to the app to simulate users checking their text messages.

Non-interactive testing

For non-interactive phone authentication testing, use the Authentication emulator REST API to retrieve available SMS codes. Note that the code is different every time you initiate the flow.

The typical sequence is as follows.

  1. Call platform signInWithPhoneNumber to start the verification process.
  2. Retrieve the verification code using the emulator-specific REST endpoint.
  3. Call confirmationResult.confirm(code) as usual with the verification code.

Multi-factor SMS

The Authentication emulator supports prototyping and testing the SMS multi-factor authentication (MFA) flows available in production for iOS, Android, and web.

When you add a mock user to the emulator, you can enable MFA and configure one or more phone numbers to which second factor SMS messages will be sent. Messages are output to the same terminal at which you ran firebase emulators:start, and available from the REST interface.

Emulated third-party identity provider (IDP) authentication

The Authentication emulator lets you test many third-party authentication flows in your iOS, Android or web apps with no changes from production code. For examples of authentication flows, consult the documentation for various combinations of providers and platforms you can use in your app.

Generally speaking, you can use the Firebase SDK to authenticate in one of two ways:

  • Your app lets the SDK handle the entire process end-to-end, including all interactions with third-party IDP providers to retrieve credentials.
  • Your app manually retrieves credentials from a third-party provider using that party's SDK and passes those credentials on to the Authentication SDK.

Again, check the documentation link above and make sure you're familiar with whichever flow - Firebase SDK-managed vs. manual credential retrieval - you want to use. The Authentication emulator supports testing of either approach.

Testing Firebase SDK-driven IDP flows

If your app uses any Firebase SDK end-to-end flow, like OAuthProvider for sign-in with Microsoft, GitHub, or Yahoo, for interactive testing, the Authentication emulator serves a local version of the corresponding sign-in page to help you test authentication from web apps that call the signinWithPopup or signInWithRedirect method. This locally-served sign-in page also appears in mobile apps, rendered by your platform's webview library.

The emulator creates mock third-party user accounts and credentials as needed as the flows proceed.

Testing IDP flows with manual credential retrieval

If you use "manual" sign-in techniques and call your platform's signInWithCredentials method, then, as usual, your app will request real third-party sign-in and retrieve real third-party credentials.

Note that the emulator only supports signInWithCredential authentication for credentials retrieved from Google Sign-In, Apple, and other providers that use ID tokens implemented as JSON Web Tokens (JWTs). Access tokens (e.g. those provided by Facebook or Twitter, which are not JWTs) are not supported. The next section discusses an alternative in these cases.

Non-interactive testing

One approach to non-interactive testing is to automate user clicks on the sign-in page served by the emulator. For web apps, use a control interface like WebDriver. For mobile, use the UI test tooling from your platform, like Espresso or Xcode.

Alternatively, you can update your code to use signInWithCredential (e.g. in a code branch) and use a token authentication flow with mock ID tokens for accounts instead of real credentials.

  1. Rewire or comment out the part of your code that retrieve idTokens from the IDP; this removes the need to input real usernames and passwords during your tests, and relieves your tests from API quotas and rate limits at the IDP.
  2. Second, use a literal JSON string in place of the token for signInWithCredential. Using the web SDK as an example, you can change the code to:
firebase.auth().signInWithCredential(firebase.auth.GoogleAuthProvider.credential(
  '{"sub": "abc123", "email": "foo@example.com", "email_verified": true}'
));

When used with the emulator, this code will successfully authenticate a user with email foo@example.com at Google. Think of the sub field as a primary key, which can be changed to any string, mocking signing in different users. You can replace firebase.auth.GoogleAuthProvider with, for example, new firebase.auth.OAuthProvider('yahoo.com') or any other provider ID you want to mock.

Emulated custom token authentication

The Authentication emulator handles authentication with custom JSON Web Tokens using calls to the signInWithCustomToken method on supported platforms, as described in the production Authentication documentation.

How the Authentication emulator differs from production

The Firebase Authentication emulator simulates many features of the production product. However, since any kind of authentication system relies heavily on security at multiple levels (device, 3rd party providers, Firebase, etc), it is difficult for the emulator to properly recreate all flows.

Cloud IAM

The Firebase Emulator Suite does not attempt to replicate or respect any IAM-related behavior for running. Emulators adhere to the Firebase Security Rules provided, but in situations where IAM would normally be used, for example to set Cloud Functions invoking service account and thus permissions, the emulator is not configurable and will use the globally-available account on your developer machine, similar to running a local script directly.

Since on mobile platforms, email link sign-in relies on Firebase Dynamic Links, all such links will be opened on the (mobile) web platform instead.

Third-party sign-in

For third-party sign-in flows, Firebase Authentication relies on secure credentials from third-party providers like Twitter and Github.

Real credentials from OpenID Connect providers such as Google and Apple are accepted by the Authentication emulator. Credentials from non-OpenID Connect providers are not supported.

Email / SMS sign-in

In production apps, email and SMS sign-in flows involve an asynchronous operation in which the user checks a received message and enters a login code into a sign-in interface. The Authentication emulator doesn't send any emails or SMS messages, but as described above, it does generate login codes and output them to the terminal to be used in testing.

The emulator does not support the ability to define test phone numbers with fixed login codes as can be done using the Firebase console.

Custom token authentication

The Authentication emulator does not validate the signature or expiry of custom tokens. This allows you to use hand-crafted tokens and re-use tokens indefinitely in prototyping and testing scenarios.

Rate limiting / anti-abuse

The Authentication emulator does not replicate production rate limiting or anti-abuse features.

Blocking functions

In production, users are written to storage once after both the beforeCreate and beforeSignIn events are triggered. However, due to technical limitations, the Authentication emulator writes to store twice, once after user creation and another after sign-in. This means that for new users, you can successfully call getAuth().getUser() in beforeSignIn in the Authentication emulator, but you would encounter an error doing so in production.

What next?