In many web applications you build, you may want to have users create (or log into) an account. Whether it's a social media application or a collaborative research tool, authentication methods can be used to restrict user access, show different data to different people, or connect users. In this learning module, you'll learn how to use Firebase's Authentication methods to create and log into accounts for your application.
Contents
- Resources
- Set up
- Promises
- Creating Users
- Logging Users In
- Logging Users Out
- Listening to Authentication Changes
- Managing Users in Firebase
- Password Authentication in Firebase
- Promises and Errors in Firebase
- JavaScript Promise Docs
In your firebase console, you'll begin by navigating to the Authentication tab using the side-bar menu of your Firebase project:
From that tab, you'll be able to see the users who have accounts for your application. Before using a specified authentication approach, you'll need to enable it in the firebase console, which is within the Sign In Method tab of your Authentication dashboard:
Simply click on the method of your choice, and use the switch in the dialog box to Enable the method. For this learning module, we'll cover using email + password authentication. Once you have enable this setting on Firebase, you'll be ready to build authentication into your JavaScript files.
Before diving into the process for authenticating users, it's important to review the concept of JavaScript Promises. As described in Module 11, many JavaScript methods return Promise objects, which are tasks which may not have completed yet. Promises provide an alternative structure to the callback function, for example:
// Request data, and process it in a callback function
$.get('PATH/TO/DATA', function(data){
// Process data in this callback function
});
// Request data, and process it once it has completed
$.get('PATH/TO/DATA').then(function(data){
// Process your data in here
});
As you can see, the .then
method of a promise accepts a function as a parameter, which will be executed once the promise has finished. To process an error, you can pass a second function to your .then
method:
// Process errors by passing in a second function to the `.then` method
$.get('PATH/TO/DATA').then(
function(data){
// Process your data in here
},
function(error) {
// Process your error in here
}
);
Note, Firebase objects (not all Promises) also expose a .catch
method, which allows you to catch any errors returned by a promise:
firebasePromise.then(function(data){
// Process your data
}).catch(function(error){
// Alert your error to your user
alert(error)
});
Firebase will return an error if you've made a request that it is unable to process, such as signing up with an email address that already exists. In order to use Firebase's authentication methods, we'll use promises to wait for requests to complete, and then process the data returned by Firebase.
The first thing we'll learn how to do is create users for web applications. Once you have loaded the Firebase library in your index.html
file, and initialized Firebase with your configuration, you'll have access to the firebase.auth()
function, which returns an authorization object that you'll use throughout your application. The object returned by firebase.auth()
has a useful (though verbosely named) signInWithEmailAndPassword
method that accepts an email and a password as parameters, and creates a user account on Firebase. We'll want to perform actions after the account is created, so we'll need to leverage Promises:
// Get email and password from a form
var email = $('#email').val();
var password = $("#password").val();
// Create a user using the values from your form
firebase.auth().createUserWithEmailAndPassword(email, password).then(function(user){
// Do something after the user has been created
});
Once the function completes, you should be able to see the new user's account on Firebase, and the user will be logged in.
Once your user has been created, you may want to set two additional properties of your user: their displayName
and photoURL
(this is the only information that you can store with your users). The user
object returned by the createUserWithEmailAndPassword
promise has an updateProfile
method that allows you to set the displayName
and photoURL
property of your user. Note, because this method is interacting with Firebase, we'll want to wait for it to finish (i.e., it returns a promise):
// Create a user using the values from your form
firebase.auth().createUserWithEmailAndPassword(email, password).then(function(user){
// Set username
user.updateProfile({
displayName:'Display Name here',
photoURL:'PHOTO/URL/HERE'
}).then(function() {
// Do something after the user's profile has been updated!
})
});
If a person has already created an account with your application, they can use their email and password to sign in using the signInWithEmailAndPassword
method of the object returned by firebase.auth()
. Again, signInWithEmailAndPassword
will return a promise, which we'll want to wait until it completes to take our next action (such as redirecting the page):
// Sign in with an email and password
firebase.auth().signInWithEmailAndPassword(email, password)
.then(function() {
// Do something here
})
.catch(function(error) {
// Alert your error to your user
});
By default, users will stay logged into your application (in the selected web browser) for 24 hours. A user may want to log out of your application, particularly if they are on a public machine, or if you're protecting sensitive information. Similarly to the approaches to sign in and sign up, the sign out function will return a promise. You can then take the desired actions after the promise has completed using the .then
method:
// Sign out, then redirect
firebase.auth().signOut().then(function() {
window.location = 'sign-up.html';
});
While Firebase allows you to get the current user by accessing firebase.auth().currentUser;
, the documentation warns that "currentUser might also be null because the auth object has not finished initializing.". So, similarly to other Firebase objects, we can listen to changes to the state of the application:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
That method will execute when the authentication is first established on page load, and when the state of the authentication changes. This is helpful for checking if the user is already logged in when the page loads.
Unfortunately, this method will fire as soon as the state changes, which might conflict with other actions we are trying to take when a user logs into our application. To avoid this, we can apply some simple JavaScript logic to prevent any interference:
var checked; // create an undefined object
firebase.auth().onAuthStateChanged(function(user) {
if(checked !== true){
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
checked = true;
}
});
To practice building an application that requires user authentication, see exercise-1.