Firebase Auth + React
Tags: react, firebase, authentication, stepbystep
Published: 2020-10-11 21:36:32

Hi! I recently learned how to enable authentication in my React application via Firebase. The process is somewhat straight forward once you connect the dots but it took me some time to find those dots and connection :p

So I thought to myself, why not document it so you can also enable authentication in your application! :)

I would really appreciate your feedback to improve this post. Lets get started: 

### Step 1: Setup Firebase Project
Before integrating Firebase into our React project, I'll go over configuring a project in Firebase for Authentication. Go to [Firebase](https://firebase.google.com/) and click on `Go to console` button on top right corner.

You'll be redirected to your list of firebase projects. Create a new project. I'll name mine "test".

![Create new project](https://dev-to-uploads.s3.amazonaws.com/i/p7ftiquekxk4q8krl01m.png)

![Naming project](https://dev-to-uploads.s3.amazonaws.com/i/g8qy3iy4grp41l3hwikf.png)

After entering a suitable name for your project, click `Continue` and you'll be redirected to `enable Google analytics` page. It's up to you to enable/disable this as it does not affect our setup.

Now wait for Firebase to perform its magic and setup your project...

When the project is ready, we'll be redirected to the project console. On the sidebar, you'll see a number of menu items:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4ou647k2jas0muomjplo.png)

Select Develop menu item and you'll see a list of sub-menu items:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qxwj4vhopa0dh9rvjzn7.png)

To enable authentication, we'll need to setup a sign-in method. Click on `authentication` menu-item and you'll be redirected to Authentication page. Click on `Sign-in method` and you'll be directed to the sign-in tab:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gil9gd08ctw7bj6tq5tz.png)

You'll notice that all the sign-in methods are disabled. We'll enable `Email/Password` method for our React application. When you scroll down, you'll notice the Authorized domain section where you can add domains for oAuth redirect. 

and thats it! we have setup our project but how will we connect this project to our React application?

Glad you asked, that'll be done by fetching the configuration details. Before we do that, we'll need to setup a web app in firebase.

### Step 2: Setup Firebase Web-App
To setup the web app, we'll need to go to homepage of our console, click on the `Project Overview` menu-item in the side-bar.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/btsy5x7in2fnxlcvnll0.png)

In the main dashboard page, select the `</>` button as highlighted below:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cc83exvjzw7b9cstw4g6.png)

Clicking on this button will slide-in a window with title: `Add Firebase to your web app`. I'll name mine `test-app`. If you would like to use firebase for hosting your application, you can check the box. However, I'll not cover that step in this post.

When you click on `Register app` button, you'll be presented with two script tags containing important configuration that'll help us to connect the firebase project to the React application.

It'll look like this:

```
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.23.0/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
     https://firebase.google.com/docs/web/setup#available-libraries -->

<script>
  // Your web app's Firebase configuration
  var firebaseConfig = {
    apiKey: "XXXXXX",
    authDomain: "XXXXX",
    databaseURL: "XXXXXX",
    projectId: "XXXXXX",
    storageBucket: "XXXXXX",
    messagingSenderId: "XXXXXX",
    appId: "XXXXXXX"
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
</script>
```

Perfect! Now we have the necessary credentials needed to enable firebase authentication in our React app. Next up we'll configure our React app.

### Step 3: Enable Firebase Auth in React App
I'll skip over the steps where you have done `create-react-app`, created your application and can do `npm run start` to get it running.

We'll start with installing the firebase package. Use the terminal to go inside the root directory of your react app and type following:

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

#### Step 3a: Setup .env file
- Create a .env file and place it in the root directory of your React project. 
**Important:** Make sure you have added the file in .gitignore since the content of .env file is confidential.

```
REACT_APP_API_KEY=XXX
REACT_APP_AUTH_DOMAIN=XXX
REACT_APP_DATABASE_URL=XXX
REACT_APP_PROJECT_ID=XXX
REACT_APP_STORAGE_BUCKET=XXX
REACT_APP_MESSAGING_SENDER_ID=XXX
REACT_APP_APP_ID=XXX
```

The value of these keys is the configuration data that we collected from `step 2`.

#### Step 3b: Create Firebase Component
Create a component named Firebase.js that will be used to initialize our Firebase instance.

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

const config = {
    apiKey: process.env.REACT_APP_API_KEY,
    authDomain: process.env.REACT_APP_AUTH_DOMAIN,
    databaseURL: process.env.REACT_APP_DATABASE_URL,
    projectId: process.env.REACT_APP_PROJECT_ID,
    storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
    messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
};

firebase.initializeApp(config);
export const auth = firebase.auth();
```

### Step 3c: Utilize Firebase auth via React Context
React allows sharing of data globally among component tree via context. We'll create an Auth context component that'll handle all the functions related to authentication: Sign-in, Sign-out and Sign-up

```
import React, {createContext, useEffect, useState} from 'react';
import {auth} from "../components/Firebase";

export const AuthContext = createContext(null);

export const AuthProvider = (props) => {
    const [userState, setUserState] = useState(null);
    const [authPending, setAuthPending] = useState(true);

    const signIn = (username, password) => {
        return auth.signInWithEmailAndPassword(username, password);
    }

    const signUp = (username, password) => {
        return auth.createUserWithEmailAndPassword(username, password);
    }

    const signOut = () => auth.signOut();

    useEffect(() => {
        return auth.onAuthStateChanged((userAuth) => {
            console.log(userAuth);
            setUserState(userAuth);
            setAuthPending(false);
        })
    }, [])

    if (authPending) {
        return (
            <div style={{
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                height: "100vh"}}
            >
                <div>Authentication in progress</div>
            </div>
        )
    }

    return (
        <AuthContext.Provider value={{
            signIn: signIn,
            signUp: signUp,
            signOut: signOut,
            userState: userState
        }}>
            {props.children}
        </AuthContext.Provider>
    )
}
```
Now we need to provide the global data and functions via `AuthProvider`. 

This is our index.js file:

```
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import {AuthProvider} from "./context/AuthContext";

ReactDOM.render(
    <React.StrictMode>
        <AuthProvider>
            <App/>
        </AuthProvider>
    </React.StrictMode>,
    document.getElementById("root")
);
```

That's it! Now you can use these functions in your application for authentication.