In this problem set, we'll walk through setting up an application powered by Firebase. Make sure to reference the course book chapter for details.
This project was bootstrapped with Create React App.
In this exercise, we'll build an authentication system for a React application. Before getting started, make sure that:
-
You have your account set up on Firebase (instructions).
-
You create a new project for this exercise.
In your src/index.js file, do the following:
-
Import necessary modules:
firebase(from'firebase/app'), and bootstrap styles ('bootstrap/dist/css/bootstrap.css'). -
Copy and paste the configuration object from the Firebase web console into a new script
Config.js. Make sure to add this filename to your.gitignorefile (so that your private key isn't added to GitHub). Then, import that object into yourindex.jsscript and pass theconfigobject into thefirebase.initializeApp()function. Do this before you render your<App>.
You are now ready to integrate the app into your application.
To start using Firebase's authentication services, you'll need to use the onAuthStateChanged() method. This will watch for changes to the authentication status, and fire a callback function, which is powerful because it will automatically fire when you execute the methdos described below. Because this method should only be executed once, you should write it in the componentDidMount() method. It should:
- Check if there is a
user(the name we will give to the callback argument of the function). - If there is a user, set the state of the application such that the
useris equal to theuser. It will also help (for future functionality) to reset the email, password, and username to an empty string (''). - If there is not a user, set the state of the
usertonull. This will happen when the user signs out.
We'll start by adding a sign up method that will allow users to sign-up for your application using their email and a password. To do this, we'll need to manipulate our app as follow:
- Add a method to our app
handleChange()that will track the state of theemail,password, anddisplayNameentered by the user. This event should be fired by each input element of the form, updating thestateof the application appropriately. - Add a method to our app
handleSignUp()that will:- Use Firebase's
createUserWithEmailAndPassword()to create a new user using the email and password currently stored in the state. When that method is successful(i.e., in the callback)... - It should set the
displayNameproperty of the newly created user (using theupdateProfilemethod), then, - It should change the state of the current user. And,
- It should
catchany errors, and update theerrorMessageproperty of the application state. This will likely reveal issues that you need to resolve.
- Use Firebase's
- Assign the
handleSignUp()method as an event listener to theSign Upbutton.
You should now be able to create users through your form, catch errors (that are provided by Firebase), and see newly created users on Firebase!
In this section, we'll provide the necessary functionality to enable users (who have already been created) to sign-in. Because of the work we did on set-up, this step is quite straightforward:
- Add a new
handleSignIn()method that leverages Firebase'ssignInWithEmailAndPasswordmethod. When this changes, theonAuthStateChanged()callback will execute, and should update our state properly. - Just in case, make sure to
catchany errors. - Assign the
handleSignIn()method as an event listener to theSign Inbutton.
In this section, we'll provide the necessary functionality to enable users (who are logged in) to sign-out.
- Add a new
handleSignOut()method that leverages Firebase'ssignOutmethod. When this changes, theonAuthStateChanged()callback will execute, and should update our state properly. - Assign the
handleSignOut()method as an event listener to theSign Outbutton.
To make a more sensible application, certain information should be conditionally displayed. In the render() method, define the following content that holds different values depending on the state of the application:
- A
welcomeDivthat contains the content<div>Hello, {this.state.user.displayName}</div>. However, ifthis.state.userisnull, it should only contain an empty string (""). Render yourwelcomeDivabove your form. - An
errorDivthat contains the content<div>Error: {this.state.errorMessage}</div>. However, ifthis.state.errorMessageisnull, it should only contain an empty string (""). Render yourerrorMessageabove your form.
You should apply a similar methodology to only show relevant parts of the form. For example, the Sign Out button should not be displayed (or shouldn't be actve) if there is no user.