Handling user authentication with Firebase in your React apps
Tags: firebase, react, tutorial
Published: 2020-03-23 17:46:54

---
title: Handling user authentication with Firebase in your React apps
published: true
date: 2020-03-05 19:00:17 UTC
tags: firebase,react,tutorial
canonical_url: https://blog.logrocket.com/user-authentication-firebase-react-apps/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ockpru06hlpfwld0y9nq.jpeg
---
**Written by [Yusuff Faruq](https://blog.logrocket.com/author/yusufffaruq/)**✏️

Sometimes, while building an application, we want each user to have a personalized experience. This is made possible through user authentication, whereby a user logs in to the application to access personalized information such as a social media feed or use a personalized service.

In this article, we will which is a backend-as-a-service (BaaS) that allows both web and mobile developers to perform common backend tasks with no need for maintenance or upkeep.

At the end of this article, we will have built a simple React app that logs users in and displays their username, email, and profile picture. You can find a demo of the application [here](https://firebase-auth-article.netlify.com/).

## Prerequisites

This article is primarily targeted towards intermediate-level React developers. However, no matter your skill level, you can still follow along well if you have an understanding of routing, the [Context API](https://dev.to/bnevilleoneill/use-hooks-context-not-react-redux-1j08), and other concepts that will be used in this article.

We will be using [Tailwind CSS](https://tailwindcss.com/) to style our components. Tailwind CSS is a utility-first CSS framework for rapidly building custom designs. It is very similar to Bootstrap, so it’s easy to pick up. You do not need to have a solid understanding of Tailwind CSS to follow along with this article.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## Setting up

Before we begin coding, we need to set up some things for our app to work. Firstly, we need to create a new React app. You can easily do that using create-react-app:

```jsx
npx create-react-app firebase-auth-app
```

Now that we have done that, we need to set up Tailwind CSS to work with React. [Here’s a great guide](https://dev.to/hagnerd/setting-up-tailwind-with-create-react-app-4jd) that helps you get Tailwind CSS up and running with create-react-app in minutes.

Next, we need to install Firebase:

```jsx
npm install --save firebase
```

With that done, we can now set up Firebase.

## Setting up Firebase

Firstly, we need to create a new file dedicated to Firebase. Create a `src` folder in the root directory, and in it, create a file called `firebase.js`.

Now, go to the [Firebase website](https://firebase.google.com/) and click on the **Get started** button. You will be taken to a page where you can create a new project. Once you are done, you should be taken to a dashboard page similar to the image below.

![The Firebase Get Started Page](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/02/firebase-get-started-page.jpeg?resize=730%2C321&ssl=1)

We will be using two Firebase services for this project: the Authentication service and Cloud Firestore service. Let’s set up Cloud Firestore first.

Select the **Database** option from the side menu. You should now be able to choose either of the two database services that Firebase provides: Cloud Firestore or the Realtime Database. In this article, we will use Cloud Firestore.

![Cloud Firestore Page](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/cloud-firestore-page.jpeg?resize=730%2C260&ssl=1)

Now create a Cloud Firestore database. You should now see a modal for setting the security rules of your database. Choose **Start in test mode**. You should have an empty database ready for use. It should look like this:

![Empty Database Page](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/empty-database-page.jpeg?resize=728%2C421&ssl=1)

Now that we have our database ready, let’s set up authentication. From the side menu, select the **Authentication** option. Now, select the **Sign-in method** tab. You should have something like this:

![Sign-in Method Page](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/sign-in-method-page.jpeg?resize=730%2C402&ssl=1)

Here, you can set up authentication for different providers such as Google, Facebook, GitHub, and so on. In our app, we want to enable Google authentication and email/password authentication. Let’s set up Google authentication first. Click on the Google option.

![Google Authentication Setup Page](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/google-authentication-setup.jpeg?resize=730%2C379&ssl=1)

You can now enable Google authentication by toggling the button at the upper right-hand side. You also need to provide a project support email. Once that is done, save the changes and do the same with the email/password option.

Now that Cloud Firestore and authentication have been set up, we need to get our project’s configuration details. This is needed to link our code to our Firebase project.

To get our Firebase configuration details, go back to the project overview page and add a web app to the Firebase project. After registering the app, you should get the configuration details in the form of a JavaScript object.

```jsx
const firebaseConfig = {
  apiKey: 'AIzaXXXXXXXXXXXXXXXXXXXXXXX',
  authDomain: 'test-XXXX.firebaseapp.com',
  databaseURL: 'https://test-XXXXXX.firebaseio.com',
  projectId: 'test-XXXX',
  storageBucket: 'test-XXXX.appspot.com',
  messagingSenderId: 'XXXXXXX',
  appId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
};
```

Now open your `firebase.js` file and import Firebase, Cloud Firestore, and Firebase’s Authentication service:

```jsx
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";

const firebaseConfig = {
  apiKey: 'AIzaXXXXXXXXXXXXXXXXXXXXXXX',
  authDomain: 'test-XXXX.firebaseapp.com',
  databaseURL: 'https://test-XXXXXX.firebaseio.com',
  projectId: 'test-XXXX',
  storageBucket: 'test-XXXX.appspot.com',
  messagingSenderId: 'XXXXXXX',
  appId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
};
```

Now we just need to initialize our Firebase app using the configuration details we got from Firebase. Once that is done, we need to get references to Cloud Firestore and the Authentication service and export them.

```jsx
firebase.initializeApp(firebaseConfig);
export const auth = firebase.auth();
export const firestore = firebase.firestore();
```

## Building our components

Now that Firebase is fully set up, we can start building our components. Our application will cover:

- Signing in and signing out
- Signing up with Google or email/password
- Password reset
- A profile page

Therefore, we will build five components:

- An `Application` component, which will render either the sign-in/sign-up routes or the profile page, depending on whether the user has been signed into the application
- A `PasswordReset` component, which allows the user to reset their password in the event they lose or forget it
- A `ProfilePage` component, which will display the user’s display name, email, and profile picture or a placeholder image if they are signing in via email/password
- A `SignIn` component for logging the user in to the application
- A `SignUp` component, which allows new users to sign up to use the application

Reach router will be used to route between the sign-in and sign-up routes or pages. Reach router is an accessibility-focused routing library for React. It is very easy to get started with and is a perfect fit for our application.

Now that we know what we want to do, let’s start writing some code!

In your `src` folder, create a new folder called `Components`. This is where our components will reside. Let’s start with the `Application` component.

The `Application` renders the `ProfilePage` component if the user has logged in and a `Router` component (which comes from Reach Router) housing the `SignUp`, `SignIn`, and `PasswordReset` components/routes otherwise.

Later on, we will use React’s Context API to pass the current user to all the components that need it. For now, we will just create a placeholder variable to represent the current user.

In case you are not familiar with Reach Router, the `Router` component is used to house the different routes we want to route between. Each immediate child of the `Router` component must have a `path` prop, which acts as a link to that route.

```jsx
import React from "react";
import { Router } from "@reach/router";
import SignIn from "./SignIn";
import SignUp from "./SignUp";
import ProfilePage from "./ProfilePage";
import PasswordReset from "./PasswordReset";
function Application() {
  const user = null;
  return (
        user ?
        <ProfilePage />
      :
        <Router>
          <SignUp path="signUp" />
          <SignIn path="/" />
          <PasswordReset path = "passwordReset" />
        </Router>

  );
}
export default Application;
```

Now, let’s build our `SignIn` component. The code for that is as follows:

```jsx
import React, {useState} from "react";
import { Link } from "@reach/router";

const SignIn = () => {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [error, setError] = useState(null);
    const signInWithEmailAndPasswordHandler = 
            (event,email, password) => {
                event.preventDefault();
    };

      const onChangeHandler = (event) => {
          const {name, value} = event.currentTarget;

          if(name === 'userEmail') {
              setEmail(value);
          }
          else if(name === 'userPassword'){
            setPassword(value);
          }
      };

  return (
    <div className="mt-8">
      <h1 className="text-3xl mb-2 text-center font-bold">Sign In</h1>
      <div className="border border-blue-400 mx-auto w-11/12 md:w-2/4 rounded py-8 px-4 md:px-8">
        {error !== null && <div className = "py-4 bg-red-600 w-full text-white text-center mb-3">{error}</div>}
        <form className="">
          <label htmlFor="userEmail" className="block">
            Email:
          </label>
          <input
            type="email"
            className="my-1 p-1 w-full"
            name="userEmail"
            value = {email}
            placeholder="E.g: faruq123@gmail.com"
            id="userEmail"
            onChange = {(event) => onChangeHandler(event)}
          />
          <label htmlFor="userPassword" className="block">
            Password:
          </label>
          <input
            type="password"
            className="mt-1 mb-3 p-1 w-full"
            name="userPassword"
            value = {password}
            placeholder="Your Password"
            id="userPassword"
            onChange = {(event) => onChangeHandler(event)}
          />
          <button className="bg-green-400 hover:bg-green-500 w-full py-2 text-white" onClick = {(event) => {signInWithEmailAndPasswordHandler(event, email, password)}}>
            Sign in
          </button>
        </form>
        <p className="text-center my-3">or</p>
        <button
          className="bg-red-500 hover:bg-red-600 w-full py-2 text-white">
          Sign in with Google
        </button>
        <p className="text-center my-3">
          Don't have an account?{" "}
          <Link to="signUp" className="text-blue-500 hover:text-blue-600">
            Sign up here
          </Link>{" "}
          <br />{" "}
          <Link to = "passwordReset" className="text-blue-500 hover:text-blue-600">
            Forgot Password?
          </Link>
        </p>
      </div>
    </div>
  );
};
export default SignIn;
```

As you can see, our `SignIn` component has three pieces of state: `email`, for storing the user’s email address; `password`, for storing the user’s password; and `error`, for displaying error messages in the event of an error during the sign-in process.

Our `SignIn` component also uses the `Link` component that Reach Router provides. This component is very similar to the anchor element in HTML, and the `to` prop of the `Link` component is similar in function to the `href` attribute of the anchor element.

Your `SignIn` component should look like this:

![Our SignIn Component](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/signin-component.jpeg?resize=730%2C472&ssl=1)

Next, let’s build our `SignUp` component. The `SignUp` component is very similar to the `SignIn` component, and the code is as follows:

```jsx
import React, { useState } from "react";
import { Link } from "@reach/router";
const SignUp = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [displayName, setDisplayName] = useState("");
  const [error, setError] = useState(null);
  const createUserWithEmailAndPasswordHandler = (event, email, password) => {
    event.preventDefault();
    setEmail("");
    setPassword("");
    setDisplayName("");
  };
  const onChangeHandler = event => {
    const { name, value } = event.currentTarget;
    if (name === "userEmail") {
      setEmail(value);
    } else if (name === "userPassword") {
      setPassword(value);
    } else if (name === "displayName") {
      setDisplayName(value);
    }
  };
  return (
    <div className="mt-8">
      <h1 className="text-3xl mb-2 text-center font-bold">Sign Up</h1>
      <div className="border border-blue-400 mx-auto w-11/12 md:w-2/4 rounded py-8 px-4 md:px-8">
        {error !== null && (
          <div className="py-4 bg-red-600 w-full text-white text-center mb-3">
            {error}
          </div>
        )}
        <form className="">
          <label htmlFor="displayName" className="block">
            Display Name:
          </label>
          <input
            type="text"
            className="my-1 p-1 w-full "
            name="displayName"
            value={displayName}
            placeholder="E.g: Faruq"
            id="displayName"
            onChange={event => onChangeHandler(event)}
          />
          <label htmlFor="userEmail" className="block">
            Email:
          </label>
          <input
            type="email"
            className="my-1 p-1 w-full"
            name="userEmail"
            value={email}
            placeholder="E.g: faruq123@gmail.com"
            id="userEmail"
            onChange={event => onChangeHandler(event)}
          />
          <label htmlFor="userPassword" className="block">
            Password:
          </label>
          <input
            type="password"
            className="mt-1 mb-3 p-1 w-full"
            name="userPassword"
            value={password}
            placeholder="Your Password"
            id="userPassword"
            onChange={event => onChangeHandler(event)}
          />
          <button
            className="bg-green-400 hover:bg-green-500 w-full py-2 text-white"
            onClick={event => {
              createUserWithEmailAndPasswordHandler(event, email, password);
            }}
          >
            Sign up
          </button>
        </form>
        <p className="text-center my-3">or</p>
        <button
          className="bg-red-500 hover:bg-red-600 w-full py-2 text-white"
        >
          Sign In with Google
        </button>
        <p className="text-center my-3">
          Already have an account?{" "}
          <Link to="/" className="text-blue-500 hover:text-blue-600">
            Sign in here
          </Link>
        </p>
      </div>
    </div>
  );
};
export default SignUp;
```

Our `SignUp` component should look like this:

![Our SignUp Component](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/signup-component.jpeg?resize=730%2C483&ssl=1)

Now let’s build our `ProfilePage` component. We will use placeholder values for the profile picture, email, and display name. The code for the `ProfilePage` should look like this:

```jsx
import React from "react";

const ProfilePage = () => {
  return (
    <div className = "mx-auto w-11/12 md:w-2/4 py-8 px-4 md:px-8">
      <div className="flex border flex-col items-center md:flex-row md:items-start border-blue-400 px-3 py-4">
        <div
          style={{
            background:
                `url(https://res.cloudinary.com/dqcsk8rsc/image/upload/v1577268053/avatar-1-bitmoji_upgwhc.png)  no-repeat center center`,
            backgroundSize: "cover",
            height: "200px",
            width: "200px"
          }}
          className="border border-blue-300"
        ></div>
        <div className = "md:pl-4">
        <h2 className = "text-2xl font-semibold">Faruq</h2>
        <h3 className = "italic">faruq123@gmail.com</h3>
        </div>
      </div>
      <button className = "w-full py-3 bg-red-600 mt-4 text-white">Sign out</button>
    </div>
  ) 
};
export default ProfilePage;
```

With that done, let’s move to the `PasswordReset` component. This is where the user can input their email into a form and have a password reset email sent to them in case they lose their password. The code for this component is as follows:

```jsx
import React, { useState } from "react";
import { Link } from "@reach/router";

const PasswordReset = () => {
  const [email, setEmail] = useState("");
  const [emailHasBeenSent, setEmailHasBeenSent] = useState(false);
  const [error, setError] = useState(null);
  const onChangeHandler = event => {
    const { name, value } = event.currentTarget;
    if (name === "userEmail") {
      setEmail(value);
    }
  };
  const sendResetEmail = event => {
    event.preventDefault();
  };
  return (
    <div className="mt-8">
      <h1 className="text-xl text-center font-bold mb-3">
        Reset your Password
      </h1>
      <div className="border border-blue-300 mx-auto w-11/12 md:w-2/4 rounded py-8 px-4 md:px-8">
        <form action="">
          {emailHasBeenSent && (
            <div className="py-3 bg-green-400 w-full text-white text-center mb-3">
              An email has been sent to you!
            </div>
          )}
          {error !== null && (
            <div className="py-3 bg-red-600 w-full text-white text-center mb-3">
              {error}
            </div>
          )}
          <label htmlFor="userEmail" className="w-full block">
            Email:
          </label>
          <input
            type="email"
            name="userEmail"
            id="userEmail"
            value={email}
            placeholder="Input your email"
            onChange={onChangeHandler}
            className="mb-3 w-full px-1 py-2"
          />
          <button
            className="w-full bg-blue-400 text-white py-3"
          >
            Send me a reset link
          </button>
        </form>
        <Link
         to ="/"
          className="my-2 text-blue-700 hover:text-blue-800 text-center block"
        >
          &larr; back to sign in page
        </Link>
      </div>
    </div>
  );
};
export default PasswordReset;
```

## Passing down the current user with the Context API

Like I pointed out earlier, we will pass down the current user to all the components that need it using React’s Context API.

The Context API allows us to pass data down a tree of components without pass that data as props of intermediate components. Therefore, regardless of how deeply nested in a component tree a component may be, it will have easy access to whatever data is stored in the context. You can learn more about Context [here](https://reactjs.org/docs/context.html).

To pass down the data from Context, we will use a provider component that will house the `Application` component in our `App.js` file.

You can create a `providers` folder in your `src` folder. Inside the providers folder, create a new file called `UserProvider.jsx`. Import `createContext` alongside React. We also need to import `auth` from our `firebase.js` file. With that done, let’s create and export our context, which we will call `UserContext`. Its initial value will be an object with a property called `user`, whose value is `null`.

```jsx
export const UserContext = createContext({ user: null });
```

Now let’s create the actual `UserProvider` component. We need to add a piece of state in the `UserProvider` component called `user`. This piece of state will later be passed down to the other components as the value of the `UserContext` context.

We also need to perform some operations as soon as the `UserProvider` component mounts. Firebase gives us an observer called `onAuthStateChanged`, which we can set on the `auth` object to listen for changes in the state of the current user (when the user logs in and logs out).

We can also get the current user and some information about that user, such as uid, email, display name, and so on, with `onAuthStateChanged`. What we want to do is get the current user and set it as the value of the `user` state. In this case, our current user is `userAuth`.

```jsx
componentDidMount = () => {
    auth.onAuthStateChanged(userAuth => {
      this.setState({ user: userAuth});
    });
};
```

Our `UserProvider` component can now render the provider component that comes with our `UserContext` and, in turn, house the child components passed to it. Our `UserProvider` component should look like this:

```jsx
import React, { Component, createContext } from "react";
import { auth } from "../firebase";

export const UserContext = createContext({ user: null });
class UserProvider extends Component {
  state = {
    user: null
  };

  componentDidMount = () => {
    auth.onAuthStateChanged(userAuth => {
      this.setState({ user: userAuth});
    });
  };
  render() {
    return (
      <UserContext.Provider value={this.state.user}>
        {this.props.children}
      </UserContext.Provider>
    );
  }
}
export default UserProvider;
```

Once we have our `UserProvider` ready, we will use it to wrap our `Application` component in our `App.js` file.

```jsx
import React from "react";
import Application from "./Components/Application";
import UserProvider from "./providers/UserProvider";
function App() {
  return (
    <UserProvider>
      <Application />
    </UserProvider>
  );
}
export default App;
```

## Implementing Google sign-in

Implementing Google sign-in with Firebase is simple. Let’s go to our `firebase.js` file and create a variable called `provider`, whose value will be an instance of the Google provider object.

```jsx
const provider = new firebase.auth.GoogleAuthProvider();
```

Firebase Auth provides different methods of signing in, such as `signInWithRedirect`, which redirects the user to a new page, and `signInWithPopup`, which makes use of a pop-up. After choosing our sign-in method, we can now write and export our simple Google sign-in function:

```jsx
export const signInWithGoogle = () => {
  auth.signInWithPopup(provider);
};
```

We can now use this `SignInWithGoogle` function in the `onClick` handler functions for the **Sign In with Google** button in our `SignIn` and `SignUp` components.

Now, when you sign in with your Google account, you should be signed in to the application and taken to your profile page where you should see your display name, email, and display picture. However, because we are still using the placeholder values in the `ProfilePage`, this is not so. Also, the **Sign out** button doesn’t work so we need to modify our `ProfilePage`, like so:

```jsx
import React, { useContext } from "react";
import { UserContext } from "../providers/UserProvider";
import {auth} from "../firebase";
const ProfilePage = () => {
  const user = useContext(UserContext);
  const {photoURL, displayName, email} = user;
  return (
    <div className = "mx-auto w-11/12 md:w-2/4 py-8 px-4 md:px-8">
      <div className="flex border flex-col items-center md:flex-row md:items-start border-blue-400 px-3 py-4">
        <div
          style={{
            background: `url(${photoURL || 'https://res.cloudinary.com/dqcsk8rsc/image/upload/v1577268053/avatar-1-bitmoji_upgwhc.png'})  no-repeat center center`,
            backgroundSize: "cover",
            height: "200px",
            width: "200px"
          }}
          className="border border-blue-300"
        ></div>
        <div className = "md:pl-4">
        <h2 className = "text-2xl font-semibold">{displayName}</h2>
        <h3 className = "italic">{email}</h3>
        </div>
      </div>
      <button className = "w-full py-3 bg-red-600 mt-4 text-white" onClick = {() => {auth.signOut()}}>Sign out</button>
    </div>
  ) 
};
export default ProfilePage;
```

As you can see, we used the `useContext` Hook to get the current value of `UserContext` and grabbed the necessary data from it. We also added an `onClick` handler to our sign-out button. This function uses the `signOut` method provided by the auth object.

Now you should be able to see your correct details on your profile page.

## Implementing email/password sign-in

When we implement email/password authentication, we cannot add additional data such as display name on user creation. As a solution, we will save and retrieve each user’s data on Cloud Firestore. This article will not discuss Cloud Firestore in detail but will cover the parts of Cloud Firestore we need to understand. You can visit [the docs](https://firebase.google.com/docs/firestore) to learn more about Firestore.

So what is Cloud Firestore, and how does it store data? Well, [according to the docs](https://firebase.google.com/docs/firestore/data-model):

> Cloud Firestore is a NoSQL, document-oriented database. Unlike a SQL database, there are no tables or rows. Instead, you store data in documents, which are organized into collections.
> 
> Each document contains a set of key-value pairs. Cloud Firestore is optimized for storing large collections of small documents.

So, for our application, we will create a collection called `users`, which will contain documents for each user. These documents will contain information about the user, such as display name, email, and photo URL. We will also create an async function called `generateUserDocument`, which will then return the user data with the help of another function called `getUserDocument`.

Now, let’s write our `generateUserDocument` function in our `firebase.js` file. First of all, we need to get a reference to the user’s document in the `users` collection. We can do this with the `doc` method that Firestore provides. Once that’s done, we need to get the current content of the document, and we can do this with the `get` method of the user reference.

```jsx
const userRef = firestore.doc(`users/${user.uid}`);
const snapshot = await userRef.get();
```

We now want to check if there is data at the specified reference. If there is no data, we want to write some data to that document. After that, we will return the user’s data using the `getUserDocument` function. If there is data, we will return the user’s data right away.

```jsx
export const generateUserDocument = async (user, additionalData) => {
  if (!user) return;
  const userRef = firestore.doc(`users/${user.uid}`);
  const snapshot = await userRef.get();
  if (!snapshot.exists) {
    const { email, displayName, photoURL } = user;
    try {
      await userRef.set({
        displayName,
        email,
        photoURL,
        ...additionalData
      });
    } catch (error) {
      console.error("Error creating user document", error);
    }
  }
  return getUserDocument(user.uid);
};
const getUserDocument = async uid => {
  if (!uid) return null;
  try {
    const userDocument = await firestore.doc(`users/${uid}`).get();
    return {
      uid,
      ...userDocument.data()
    };
  } catch (error) {
    console.error("Error fetching user", error);
  }
};
```

Now that we have a function to host our users’ data on Firestore, let’s use that function in the `createUserWithEmailAndPasswordHandler` in our `SignUp` component. We can create a new user with email and password using the `createUserWithEmailAndPassword` method provided by Firebase, and then generate a user document for the new user with our new function, like so:

```jsx
const createUserWithEmailAndPasswordHandler = async (event, email, password) => {
    event.preventDefault();
    try{
      const {user} = await auth.createUserWithEmailAndPassword(email, password);
      generateUserDocument(user, {displayName});
    }
    catch(error){
      setError('Error Signing up with email and password');
    }

    setEmail("");
    setPassword("");
    setDisplayName("");
  };
```

Next, let us modify the event handler for signing in using email and password in the `SignIn` component. We can sign in an already registered user using the `signInWithEmailAndPassword` method of the Firebase Auth object.

```jsx
const signInWithEmailAndPasswordHandler = (event, email, password) => {
    event.preventDefault();
    auth.signInWithEmailAndPassword(email, password).catch(error => {
      setError("Error signing in with password and email!");
      console.error("Error signing in with password and email", error);
    });
  };
```

The final thing to do in order to fully implement the email/password sign-in is to modify the `componentDidMount` method of our `UserProvider` component. Since we are no longer retrieving data directly from the user object provided by the `onAuthStateChanged` method, we need to modify our code like so:

```jsx
componentDidMount = async () => {
    auth.onAuthStateChanged(async userAuth => {
      const user = await generateUserDocument(userAuth);
      this.setState({ user });
    });
  };
```

Now, new users should be able to create an account in our application using their email and password.

## Implementing the password reset feature

It is a good idea to provide a password reset feature so users can reset their passwords in the event they lose them.

Firebase makes this very easy to do with a handy function called `sendPasswordResetEmail`, which takes in an email as an argument and sends a reset link to the email if the user has an account with our application. If the user does not have an account with our app, this function throws an error. Let’s edit the `sendResetEmail` function in our `PasswordReset` component as follows:

```jsx
const sendResetEmail = event => {
    event.preventDefault();
    auth
      .sendPasswordResetEmail(email)
      .then(() => {
        setEmailHasBeenSent(true);
        setTimeout(() => {setEmailHasBeenSent(false)}, 3000);
      })
      .catch(() => {
        setError("Error resetting password");
      });
  };
```

Now, registered users should be able to reset their passwords using the `PasswordReset` component.

## Conclusion

Finally, we have come to the end of this article!

You should now be able to authenticate users in your React apps using Firebase. Firebase also supports other authentication providers such as GitHub, Twitter, and so on, and you can learn more about authentication in Firebase [here](https://firebase.google.com/docs/auth).

You can also find the app we built live [here](https://firebase-auth-article.netlify.com/).

* * * 
## Full visibility into production React apps 

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket.](https://www2.logrocket.com/react-performance-monitoring)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/eq752g8qhbffxt3hp9t4.png)

[LogRocket](https://www2.logrocket.com/react-performance-monitoring) is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — [start monitoring for free.](https://www2.logrocket.com/react-performance-monitoring)
* * *

The post [Handling user authentication with Firebase in your React apps](https://blog.logrocket.com/user-authentication-firebase-react-apps/) appeared first on [LogRocket Blog](https://blog.logrocket.com).