Design+Code logo

Quick links

Suggested search

CodeSandbox link

You can find the full code for this tutorial at https://codesandbox.io/s/firebase-auth-ty3cd.

Set up Firebase

Make sure that you have Firebase set up in your React project. If you haven't, you can set it up by reading the section Intro to Firebase of this handbook.

Enable Firebase Auth

Go to the Firebase Console and click on Authentication, under the Build tab. Click on Get started.

Screen Shot 2021-03-17 at 12.22.57 PM

You can select any sign-in provider that you want. For this tutorial, we'll select the Email/Password option.

Screen Shot 2021-03-17 at 12.24.26 PM

Enable it, and, if you want, enable Email link (passwordless sign-in). Click on Save.

Screen Shot 2021-03-17 at 12.25.47 PM

Create the sign up form

Now is the front-end part: we need to create a sign in and a sign up form. You can scroll down to the bottom to get the final code with styling. For now, we'll create a basic form with the default input and button.

import React from "react";

const Form = () => {
    return (
        <form>
            <input placeholder="Email" />
            <input placeholder="Password" type="password" />
            <button type="submit">Sign up</button>
        </form>
    );
};

export default Form;

Create a useInput hook

We'll need to create a custom useInput hook that will allow us to get the value the user inputs in the Email and the Password fields. This hook is explained more in depth in the useInput Hook section of this handbook.

// useInput.js

import { useState } from "react";

const useInput = (initialValue) => {
    const [value, setValue] = useState(initialValue);

    const handleChange = (event) => {
        setValue(event.target.value);
    };

    return {
        value,
        onChange: handleChange
    };
};

export default useInput;

Let's import this hook at the top of our file.

// Form.js

import useInput from "./useInput"

We'll use this hook twice in our form, once for the email and another one for the password field.

// Form.js

const email = useInput("")
const password = useInput("")

We will spread the email and password constants to its specific input field. You can read more about it in the useInput Hook section of this handbook.

<input placeholder="Email" {...email} />
<input placeholder="Password" type="password" {...password}/>

Add the signUp function

Import the getFirebase function we created in the Intro to Firebase section of this handbook.

Let's create our signUp function. This function will allow the user to sign up to our application.

// Form.js
const firebaseInstance = getFirebase();

const signUp = async (event) => {
    event.preventDefault();

    try {
      if (firebaseInstance) {
        const user = await firebaseInstance.auth().createUserWithEmailAndPassword(email.value, password.value)
        console.log("user", user)
        alert(`Welcome ${email.value}!`);
      }
    } catch (error) {
      console.log("error", error);
      alert(error.message);
    }
};

The first line of this function will prevent the default behaviour when submitting a form - that is, it will prevent the page from being reloaded. Then, we are creating an instance of Firebase. If the instance isn't null or undefined, we will call Firebase Auth and create a user with the email and password the user provided. If all is good, the user will be printed on the console and a Welcome alert will be displayed. If there's an error, we'll also print it on the console and an alert will pop up with the error message.

Call this function on submit of the form.

// Form.js

const Form = () => {
    return (
        <form onSubmit={signUp}>
            {...}
        </form>
    );
};

Now, it's time to test your function! Fill in the sign up form, and see if the Welcome alert shows. Also, head back to the Firebase Console, under Authentication > Users, and see if a new user has really been created. You might need to refresh the page to see changes.

Screen Shot 2021-03-17 at 2.13.29 PM

Congratulations, users can now sign up to your app!

Create a sign in function

Now, you can copy the same code to create a sign in form. The only thing that is changed is the function, which will look like this:

// SignInForm.js

const firebaseInstance = getFirebase();

const signIn = async (event) => {
    event.preventDefault();

    try {
      if (firebaseInstance) {
        const user = await firebaseInstance
          .auth()
          .signInWithEmailAndPassword(email.value, password.value);
        console.log("user", user);
        alert("Welcome back!");
      }
    } catch (error) {
      console.log("error", error);
    }
};

Remember to change the onClick function to call the signIn function instead of the signUp function. If all is good, an alert saying Welcome back will be displayed. Users can now come back and sign in your app!

Use OnAuthStateChanged

When any user sign ups or sign ins, we can get the currentUser with the following function. It's best to put this function in a useEffect hook.

// App.js

// Create a currentUser state
const [currentUser, setCurrentUser] = useState(null);

// Listen to onAuthStateChanged
useEffect(() => {
    const firebase = getFirebase();

    if (firebase) {
      firebase.auth().onAuthStateChanged((authUser) => {
        if (authUser) {
          setCurrentUser(authUser.email);
        } else {
          setCurrentUser(null);
        }
      });
    }
  }, []);

Note: It's best to create a useContext hook to manage the authentication process in your React application, so that everything is centralized in one file and you won't initialize Firebase multiple times in the same project. Also, you'll be able to create a global currentUser state.

Create a sign out function

We now need to add the ability for the user to sign out. Create a signOut button. Remember to import the getFirebase function we created in the Intro to Firebase section of this handbook.

// SignOutButton.js

import React from "react";
import getFirebase from "./firebase";

const SignOutButton = () => {
  return <button>Sign out</button>;
};

export default SignOutButton;

Then, create the signOut function.

// SignOutButton.js

const firebaseInstance = getFirebase();

const signOut = async () => {
    try {
      if (firebaseInstance) {
        await firebaseInstance.auth().signOut();
        alert("Successfully signed out!");
      }
    } catch (error) {
      console.log("error", error);
    }
};

Add the signOut function onClick of the button.

// SignOutButton.js

const SignOutButton = () => {
    return <button onClick={() => signOut()}>Sign out</button>;
};

Congratulations! You just set up authentication in your React application with the ability to sign up, sign in and sign out! I invite you to read the other sections about Firebase to learn more about the other services that Firebase offers.

Final code

Here is the final code for the sign up form, along with styling:

import React from "react";
import styled from "styled-components";

import getFirebase from "./firebase";
import useInput from "./useInput";

const SignUpForm = () => {
    const firebaseInstance = getFirebase();
    const email = useInput("");
    const password = useInput("");

    const signUp = async (event) => {
        event.preventDefault();

        try {
            if (firebaseInstance) {
            const user = await firebaseInstance
                .auth()
                .createUserWithEmailAndPassword(email.value, password.value);
            console.log("user", user);
            alert(`Welcome ${email.value}!`);
            }
        } catch (error) {
            console.log("error", error);
            alert(error.message);
        }
    };

    return (
        <FormWrapper onSubmit={signUp}>
            <Title>Sign up</Title>
            <Input placeholder="Email" {...email} />
            <Input placeholder="Password" type="password" {...password} />
            <Button type="submit">Sign up</Button>
        </FormWrapper>
    );
};

export default SignUpForm;

const FormWrapper = styled.form`
    display: grid;
    justify-content: center;
    gap: 20px;
    padding-bottom: 50px;
`;

const Title = styled.h1`
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
    font-style: normal;
    font-weight: bold;
    font-size: 40px;
    line-height: 48px;
    color: #000;
    text-align: center;
`;

const Input = styled.input`
    background: rgba(255, 255, 255, 0.2);
    border-radius: 30px;
    padding: 10px 20px;
    background-blend-mode: overlay;
    background: rgba(255, 255, 255, 0.2);
    box-shadow: 0px 20px 40px rgba(31, 47, 71, 0.25), 0px 1px 5px rgba(0, 0, 0, 0.1), inset 0 0 0 0.5px rgba(255, 255, 255, 0.4);
    border: 1px solid rgba(250, 250, 250, 0.4);

    :focus {
        outline: none;
    }
`;

const Button = styled.button`
    background: linear-gradient(91.4deg, #2fb8ff 0%, #9eecd9 100%);
    padding: 12px 0;
    width: 200px;
    border: none;
    border-radius: 30px;
    color: white;
    font-weight: bold;
    font-family: Segoe UI, sans-serif;
    cursor: pointer;

    :focus {
        outline: none;
    }
`;

Learn with videos and source files. Available to Pro subscribers only.

Purchase includes access to 50+ courses, 320+ premium tutorials, 300+ hours of videos, source files and certificates.

BACK TO

Intro to Firebase

READ NEXT

Firestore

Templates and source code

Download source files

Download the videos and assets to refer and learn offline without interuption.

check

Design template

check

Source code for all sections

check

Video files, ePub and subtitles

Browse all downloads