Firebase makes authentication easy. It can integrate with your existing login server, or authenticate users with only client-side code. It has built-in functionality for email & password auth and third-party providers such as Facebook, Twitter, GitHub, and Google.
Most applications need to know the identity of a user. Knowing a user's identity allows an app to provide a customized experience and grant them permissions to access their data. The process of proving a user's identity is called authentication. Firebase provides a full set of authentication options out-of-the-box.
When a user authenticates to a Firebase app, three things happen:
uid (a unique ID), which is guaranteed to be distinct across all providers, and to never change for a specific authenticated user.
auth variable in your app's
Security and Firebase Rules becomes defined. This variable is null
for unauthenticated users, but for authenticated users it is an object containing the user's unique
(auth.uid) and potentially other data about the user. This allows you to
securely control data access on a per-user basis.
Once a user authenticates to your app, Firebase manages their session, ensuring that the user is remembered across browser or application restarts.
Firebase apps have built-in support for logging in with email & password, social login providers such as Facebook, Google, Twitter, and GitHub, and single-session anonymous login. Apps that use Firebase's built-in auth services can handle user login entirely with client-side code, saving you time and the headache of operating your own backend.
If you have existing server-side authentication or single sign-on, you can also easily integrate it with Firebase. Download one of our helper libraries to generate authentication tokens on your own servers.
Login is now a core feature of Firebase clients. Simple Login has been deprecated and documentation for this client is now available on Github.
Here is a list of the providers that Firebase applications support. Select the one that fits your needs, and follow the provider-specific steps to set it up.
| Platform | Description |
|---|---|
| Custom | Generate your own login tokens. Use this to integrate with existing authentication systems. You can also use this to authenticate server-side workers. |
| Email & Password | Let Firebase manage passwords for you. Register and authenticate users by email & password. |
| Anonymous | Build user-centric functionality without requiring users to share their personal information. Anonymous authentication generates a unique identifier for each user that lasts as long as their session. |
| Authenticate users with Facebook by writing only client-side code. | |
| Authenticate users with Twitter by writing only client-side code. | |
| GitHub | Authenticate users with GitHub by writing only client-side code. |
| Authenticate users with Google by writing only client-side code. |
For security reasons, if you're using a web-based OAuth flow (Facebook, Twitter, Github, or Google), only domains that you whitelist are allowed to initiate authentication for your app. This does not apply to Email & Password, Anonymous, or Custom authentication methods.
All Firebase applications have localhost and 127.0.0.1 enabled by default for local development and testing. They also include https://<YOUR-FIREBASE-APP>.firebaseapp.com as an authorized origin in case
you want to utilize Firebase Hosting.
Add more authorized origins to enable authentication from domains where you host your app.
Next, you need to enable the provider for your Firebase app.
The Firebase app is all set up for your provider. It's time to code.
Use the onAuth() method to listen for changes in user authentication state.
// Create a callback which logs the current auth statefunction authDataCallbackauthDataauthDataconsole"User " authData" is logged in with " authDataproviderconsole"User is logged out"// Register the callback to be fired every time auth state changesFirebase"https://<YOUR-FIREBASE-APP>.firebaseio.com"onAuthauthDataCallback
To stop listening for changes, you can use offAuth().
offAuthauthDataCallback
Additionally, you can use the getAuth() method to synchronously check authentication state.
Firebase"https://<YOUR-FIREBASE-APP>.firebaseio.com"authData getAuthauthDataconsole"User " authData" is logged in with " authDataproviderconsole"User is logged out"
When a user authenticates, the default session length is 24 hours from initial authentication. This means that the user's authentication state will automatically be persisted between page loads. You can configure the session length by navigating to the Login & Auth section of your Firebase App Dashboard and configuring the Session Length dropdown on the top right. Every auth provider has an optional remember parameter.
If remember is set to default, the session will last for the time you've configured in your App Dashboard. You can set remember to sessionOnly to limit persistence to the lifetime of the current window. The session length will be the same across all authentication providers you're using. If you're using an onAuth() callback, it will be triggered when a user reloads a page as long as their session has not expired.
The code to authenticate a user varies by provider and transport method, but they all have similar signatures and accept a callback function. Use it to handle errors and process the results of a successful login.
// Create a callback to handle the result of the authenticationfunction authHandlererror authDataerrorconsole"Login Failed!" errorconsole"Authenticated successfully with payload:" authData// Authenticate users with a custom authentication tokenauthWithCustomToken"<token>" authHandler// Alternatively, authenticate users anonymouslyauthAnonymouslyauthHandler// Or with an email/password combinationauthWithPasswordemail 'bobtony@firebase.com'password 'correcthorsebatterystaple'authHandler// Or via popular OAuth providers ("facebook", "github", "google", or "twitter")authWithOAuthPopup"<provider>" authHandlerauthWithOAuthRedirect"<provider>" authHandler
Tokens issued to the authenticated users are valid for 24 hours by default. You can change this from the Login & Auth tab on the App Dashboard.
Calling unauth() invalidates the user's token and logs them out of your application:
unauth
If you had previously used the onAuth() method to listen for authentication state,
your callback would now be invoked with null for authData.
Internally, Firebase apps generate JSON Web Tokens (JWTs) and create authenticated sessions by
calling Firebase.loginWithCustomToken() with those tokens. Each user is assigned
a uid (unique ID), a String which is guaranteed to be distinct across all providers, and to never change for
a specific authenticated user.
Applications do not automatically store profile or user state. To persist user data you must save it to your database. The callback function will return an object containing the data for the authenticated user, which you can then write to your database.
In the code sample below, we authenticate the user, and then store user data in the path https://<YOUR-FIREBASE-APP>.firebaseio.com/users/<uid>, where users/ is any arbitrary path to store user data, and <uid> represents the unique id obtained from the authentication data.
This code saves a user's information after they authenticate, using the uid as
the key for the user's profile.
// we would probably save a profile when we register new users on our site// we could also read the profile to see if it's null// here we will just simulate this with an isNewUser booleanisNewUserFirebase"https://<YOUR-FIREBASE-APP>.firebaseio.com"onAuthfunctionauthDataauthData isNewUser// save the user's profile into the database so we can list users,// use them in Security and Firebase Rules, and show profileschild"users"childauthDataprovider authDataprovidergetNameauthData// find a suitable name based on the meta info given by each providerfunction getNameauthDataswitchauthDataprovider'password'return authDatapasswordemailreplace/@.*/'twitter'return authDatatwitterdisplayName'facebook'return authDatafacebookdisplayName
When a user is saved using the above code, the /users/ node looks something like this:
"users""c20f3bea-906f-4cd6-b38a-175bb4506287""provider""password""name""bobtony""1376ecee-fc04-4809-9de9-ff41747e12a7""provider""twitter""name""Andrew Lee""9550be91-ab5d-41c1-8cd0-24c883586071""provider""facebook""name""James Tamplin"
Since the user's uid property is unique, it is the recommended key for storing users.
Firebase apps support three different ways to authenticate with OAuth providers - via pop-up, browser redirect, or credential login.
Third-party authentication methods use a browser pop-up window, or browser redirect, to prompt the user to sign-in, approve the application, and return the user's data to the requesting application.
Most modern browsers block pop-up windows unless they are invoked by direct user action.
Therefore, we should only invoke the authWithOAuthPopup() method for third-party authentication upon the
user's click.
Note: Browser popups and redirects are not available on all platforms or browser environments.
Popups are not available in Chrome for iOS, iOS Preview Panes, or local, file:// URLs.
Redirects are not available in PhoneGap / Cordova, or local, file:// URLs. Therefore, it
is recommended that you use a combination of both authentication methods to cover all environments:
Firebase"https://<YOUR-FIREBASE-APP>.firebaseio.com"// prefer pop-ups, so we don't navigate away from the pageauthWithOAuthPopup"google"functionerror authDataerrorerror"TRANSPORT_UNAVAILABLE"// fall-back to browser redirects, and pick up the session// automatically when we come back to the origin pageauthWithOAuthRedirect"google"functionerror/* ... */authData// user authenticated with Firebase
When your app calls an authentication method, you pass it a callback. This function
is invoked with the result of the authentication attempt, either an error or authData object.
All errors are Error objects containing at least code and message attributes.
In some cases, additional information will be provided via the details attribute. For example:
"TRANSPORT_UNAVAILABLE"message"There are no login transports available for the requested method."details"More details about the specific error here."
In some cases you may want to explicitly check for specific errors to notify your user, or prompt them to login again. For example, if you're using email & password authentication, you would want to check for an invalid email or password:
Firebase"https://<YOUR-FIREBASE-APP>.firebaseio.com"authWithPasswordemail "bobtony@firebase.com"password "invalid-password"functionerror authDataerrorswitcherror"INVALID_EMAIL"console"The specified user account email is invalid."break"INVALID_PASSWORD"console"The specified user account password is incorrect."break"INVALID_USER"console"The specified user account does not exist."breakdefaultconsole"Error logging user in:" errorconsole"Authenticated successfully with payload:" authData
This interactive demo demonstrates registration and login. Once the user is logged in, we save that user information to a users location in our database and take them to a screen showing all the registered users in the system.
| Error Code | Description |
|---|---|
| AUTHENTICATION_DISABLED | The requested authentication provider is disabled for this Firebase application. |
| EMAIL_TAKEN | The new user account cannot be created because the specified email address is already in use. |
| INVALID_ARGUMENTS | The specified credentials are malformed or incomplete. Please refer to the error message, error details, and Firebase documentation for the required arguments for authenticating with this provider. |
| INVALID_CONFIGURATION | The requested authentication provider is misconfigured, and the request cannot complete. Please confirm that the provider's client ID and secret are correct in your App Dashboard and the app is properly set up on the provider's website. |
| INVALID_CREDENTIALS | The specified authentication credentials are invalid. This may occur when credentials are malformed or expired. |
| INVALID_EMAIL | The specified email is not a valid email. |
| INVALID_ORIGIN | A security error occurred while processing the authentication request. The web origin for the request is not in your list of approved request origins. To approve this origin, visit the Login & Auth tab in your App Dashboard. |
| INVALID_PASSWORD | The specified user account password is incorrect. |
| INVALID_PROVIDER | The requested authentication provider does not exist. Please consult the Firebase Authentication documentation for a list of supported providers. |
| INVALID_TOKEN | The specified authentication token is invalid. This can occur when the token is malformed, expired, or the Firebase app secret that was used to generate it has been revoked. |
| INVALID_USER | The specified user account does not exist. |
| NETWORK_ERROR | An error occurred while attempting to contact the authentication server. |
| PROVIDER_ERROR | A third-party provider error occurred. Please refer to the error message and error details for more information. |
| TRANSPORT_UNAVAILABLE | The requested login method is not available in the user's browser environment. Popups are not available in Chrome for iOS, iOS Preview Panes, or local, file:// URLs. Redirects are not available in PhoneGap / Cordova, or local, file:// URLs. |
| UNKNOWN_ERROR | An unknown error occurred. Please refer to the error message and error details for more information. |
| USER_CANCELLED | The current authentication request was cancelled by the user. |
| USER_DENIED | The user did not authorize the application. This error can occur when the user has cancelled an OAuth authentication request. |
All Firebase database data is stored as JSON objects. There are no tables or records.
When we add data to the JSON tree, it becomes a key in the existing
JSON structure. For example, if we added a child named widgets
under users/mchen/, our data looks as follows:
{
"users": {
"mchen": {
"friends": { "brinchen": true },
"name": "Mary Chen",
// our child node appears in the existing JSON tree
"widgets": { "one": true, "three": true }
},
"brinchen": { ... },
"hmadi": { ... }
}
}
To read and write database data, we first create a reference to the Firebase database. This data to be loaded is specified with a URL.
new Firebase('https://docs-examples.firebaseio.com/web/data');
. $ # [
] / and ASCII control characters 0-31 and 127.
Creating a reference does not create a connection to the server or begin downloading data. Data is not fetched until a read or write operation is invoked. Once it is retrieved, it stays cached locally until the last event listener is removed.
Firebase provides an application which displays a visual representation of the database data
and provides tools for simple administrative tasks. We refer to this as the app dashboard.
All the data in this guide is stored in the docs-examples Firebase database; a read-only version
of the app dashboard can be viewed by
going to the Firebase URL
in a browser.
It's possible to directly access child nodes in the data as well. For example, to point to
Mary Chen's name, simply append users/mchen/name to the URL:
new Firebase("https://docs-examples.firebaseio.com/web/data/users/mchen/name");
We can achieve the same result from an existing parent reference by using the child() API call:
var rootRef = new Firebase('https://docs-examples.firebaseio.com/web/data');
rootRef.child('users/mchen/name');
In a similar fashion, it's possible to drill down directly to the database data in the application Dashboard by simply adding the child path to the URL.
Data can also be visualized directly in Chrome's DevTools by using Vulcan, an extension built by the Firebase team. Vulcan allows you to create, read, update and delete data for a specific Firebase database, as well as modify the structure of your Firebase database by adding a child, a branch, or arbitrary JSON to any node. Visit the Chrome App Store to download Vulcan and view the open source repository on GitHub.
Firebase databases have no native support for arrays. If we try to store an array, it really gets stored as an "object" with integers as the key names.
// we send this
['hello', 'world']
// Firebase databases store this
{0: 'hello', 1: 'world'}
However, to help developers that are storing arrays in a Firebase database, when data is
read using val() or via the REST api, if the data looks like
an array, Firebase clients will render it as an array. In particular, if all of the keys are integers,
and more than half of the keys between 0 and the maximum key in the object have non-empty values,
then Firebase clients will render it as an array. This latter part is important to keep in mind.
// we send this
['a', 'b', 'c', 'd', 'e']
// Firebase databases store this
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}
// since the keys are numeric and sequential,
// if we query the data, we get this
['a', 'b', 'c', 'd', 'e']
// however, if we then delete a, b, and d,
// they are no longer mostly sequential, so
// we do not get back an array
{2: 'c', 4: 'e'}
It's not currently possible to change or prevent this behavior. Hopefully understanding it will make it easier to see what one can and can't do when storing array-like data.
Why not just provide full array support? Since array indices are not permanent or unique, concurrent real-time editing will always be problematic.
Consider, for example, if three users simultaneously updated an array on a remote service. If user A attempts to change the value at key 2, user B attempts to move it, and user C attempts to change it, the results could be disastrous. For example, among many other ways this could fail, here's one:
// starting data
['a', 'b', 'c', 'd', 'e']
// record at key 2 moved to position 5 by user A
// record at key 2 is removed by user B
// record at key 2 is updated by user C to foo
// what ideally should have happened
['a', 'b', 'd', 'e']
// what actually happened
['a', 'c', 'foo', 'b']
So when is it okay to use an array? If all of the following are true, it's okay to store the array in your Firebase database:
remove()
A quick reference to limitations in data storage and read ops in a Firebase database.
| Description | Limit | Notes |
|---|---|---|
| Depth of child nodes | 32 | |
| Length of a key | 768 bytes | UTF-8 encoded, cannot contain . $
# [ ] /
or ASCII control characters 0-31 or 127 |
| Size of one child value | 10mb | UTF-8 encoded |
| Write from SDK | 16mb | UTF-8 encoded |
| Write from REST | 256mb | |
| Nodes in a read operation | 100 million |
Firebase performs automated backups of all Firebase databases daily. The backups are stored for 60 days at an off-site facility. Since these backups are done at the hardware level, they do not affect your bandwidth usage or performance. These backups are primarily for disaster recovery, but can be made available to developers on a case-by-case basis for purposes of emergency restores.
Firebase also offers optional, private backups to a Google Cloud Storage (GCS) bucket or an Amazon Simple Storage Solution (S3) bucket, for databases which have upgraded to the Bonfire, Blaze, or Inferno plan. Since these backups are done at the hardware level, they do not count against your bandwidth usage and do not affect performance of the database. Email support@firebase.com to enable this feature for your database.
It is also possible to create manual backups via the REST API. For databases with less than 200MB of data, this can be done by simply requesting the entire database using the root URL. For larger instances, you should break up your data by path or by key and retrieve it in smaller chunks.
Keep in mind that backing up data via the REST API does count against your bandwidth usage, and it can affect performance. Backups of large data (gigabytes) should be spread over a large time frame to reduce the impact on clients connected to the database.
For more information about chunking data and creating backups of big data, see the REST API's
query parameters.
Used together, startAt, limitToFirst, and
shallow=true arguments can be used to
index keys for any amount of data, and retrieve it in manageable segments.