Creating an Authentication Page with Firebase in React.

Creating an Authentication Page with Firebase in React.

Have you ever wondered how to create a functional login/signup page for your website? Well let me introduce you to firebase authentication then.
Firebase is a backend service created by Google, that provides users with different tools and services to help them develop websites and apps.

What is User Authentication

User authentication is a form of verification of a user’s identity. It is a security process that prevents unauthorized persons from gaining access to an app, website, or network. It is a procedure that allows users to give user credentials to a network in order to prove authenticity and be fully authorized to the network.

Firebase authentication is a method of creating a unique ID for various users in order to provide security to their profiles and prevent them from being tampered with. Firebase authentication is necessary not only for security but also for identification purposes by the app owner.

In this article, we’ll explore the process of using Firebase to create an authentication system and connect our React app to it.

Prerequisite

  • Fundamental knowledge of React.

  • A code editor and a browser.

Creating a new Firebase project

To create a new Firebase project we should first signup or login to our Firebase account. Inside the Firebase account, we will then select either mobile application or web application depending on what type of application you are working with, We will be selecting web application because we are working on a website project using the React framework.

We will then get to a page just like the image above. We can register the app by giving it a name of our choosing, then the next step will be add a firebase SDK, which will give us the settings required to initialize our app in React.
To use the settings in our React app, we will first need to install Firebase in our React app using the command npm install firebase or `yarn add firebase in the terminal of our code editor, depending on whether we’re using node or yarn.
We can then copy the second settings that we will be using in our React app, it should contain a Firebase config object, which will contain the Firebase credentials needed to link our React app with Firebase. On the Firebase website, we will then click on the “continue to console” button.

Setting up Firebase in our React App

Inside our React project, we will first install Firebase by running npm i firebase in the terminal then create a firebase.js file that will hold our Firebase config settings.

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_KEY,
  authDomain: "fir-auth-tutorial-15ee5.firebaseapp.com",
  projectId: "fir-auth-tutorial-15ee5",
  storageBucket: "fir-auth-tutorial-15ee5.appspot.com",
  messagingSenderId: "637624986163",
  appId: "1:637624986163:web:a1d6d50f2078b029961146"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

The apiKey variable is a personal variable, so it is best kept in a .env file so that It cannot be easily accessed by others. The .env file should also be in the app folder, It can then be accessed from that folder using process.env."variableName", my variable name being REACT_APP_FIREBASE_KEY.

Choosing Firebase authentication with email and password.

To select Firebase authentication with email and password, we will then go back to the Firebase website. On the sidebar under product categories and build, we will then select authentication, and then click on the get started button, this will take us to a new page where we will be able to select our sign-in method. For this article we will be using the sign-in with email and password method, so that is what you will select.

Enable the method then save. You will then be able to add new users manually from your Firebase account by using the add new provider button, but I will be showing you how to use a form to authenticate users who signup to the web app.

Creating a signup/login form.

Let’s get to it then. We will create a signup folder, which will have a Signup.js file and a signup.css. Inside the newly created Signup.js file we will then create a form that has two input fields and a button. The first will receive the value of the email that a user inputs, while the second will receive the value of the password that a user inputs. Meaning they will have a type attribute of email and password respectively. We will then create a duplicate of the first form that we created, and make each of the forms to be rendered conditionally using the ternary operator depending on if we want to signup or login, this will be controlled by the toggle variable that will be controlled by the useState hook, which will be set to a toggle variable and changed by the handleToggle function, which will be controlled by a <p> tag in the forms. We will also create event handlers for the input fields to monitor the user input and save the values to email and password as useState variables, we will also create a handleSignup function for the first form and a handleSignIn function for the second form, and these functions will serve as event handlers and prevent the page from reloading when the submit button is clicked. We will also create an error useState that will originally be set to false, this will be used later on during signing up or logging in, in case we encounter an error, and will be used in our form to conditionally render a message in case we encounter an error.

import React from "react";
import "./signup.css";
export default function Signup() {
  const [error, setError] = React.useState(false);
  const [toggle, setToggle] = React.useState(true);
  const [email, setEmail] = React.useState("");
  const [password, setPassword] = React.useState("");

  const navigate = useNavigate();

  const handleToggle = function () {
    setToggle((prevToggle) => !prevToggle);
  };
  const handleSignup = function (e) {
    e.preventDefault();

  };
  const handleSignIn = function (e) {
    e.preventDefault();
  };
  return (
    <div className="signup">
      {toggle ? (
        <form onSubmit={handleSignup}>
          <input
            type="email"
            placeholder="email"
            onChange={(e) => setEmail(e.target.value)}
          />
          <input
            type="password"
            placeholder="password"
            onChange={(e) => setPassword(e.target.value)}
          />
          <button>Sign Up</button>
          <p style={{ color: "green" }} onClick={handleToggle}>
            Already have an account?
          </p>
          {error && <span>Error, Couldn't signUp!</span>}
        </form>
      ) : (
        <form onSubmit={handleSignIn}>
          <input
            type="email"
            placeholder="email"
            onChange={(e) => setEmail(e.target.value)}
          />
          <input
            type="password"
            placeholder="password"
            onChange={(e) => setPassword(e.target.value)}
          />
          <button>Login</button>
          <p style={{ color: "green" }} onClick={handleToggle}>
            Don't have an account?
          </p>
          {error && <span>Error, Couldn't Login!</span>}
        </form>
      )}
    </div>
  );
}

Styling the signup/login form.

The Signup.js file will then be styled in the signup.css file. You can style it to suit your preference, but with minimal styling, it should look like this:

.signup {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
form {
  display: flex;
  flex-direction: column;
  text-align: center;
}
input {
  width: 25vw;
  height: 30px;
  font-size: 18px;
}
button {
  background-color: royalblue;
  height: 40px;
  color: white;
  font-size: 16px;
  cursor: pointer;
}
p {
  cursor: pointer;
}
span {
  color: red;
}

Creating a Route to the homepage.

In our terminal we will then install react-router-dom with the command npm i react-router-dom, then in our index.js file we will import BrowserRouter, Routes and Route from react-router-dom, We will also import our Signup.js file. Now our <App/> JSX element and the imported <Signup/> JSX element should be wrapped up in a <BrowserRouter> JSX element and then a <Routes> JSX element. The <App> and <Signup> JSX elements should then be wrapped up by individual <Route> JSX elements which will have attributes of path and element, the path attribute containing the URL path, and the element containing the JSX element. The end result will look like this:

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Signup from "./signup/Signup";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Signup />} />
        <Route path="/home" element={<App />} />
      </Routes>
    </BrowserRouter>
  </React.StrictMode>
);


reportWebVitals();

Getting the Firebase auth SDK.

We will then import getAuth from Firebase and then import it into our firebase.js file. The imported getAuth function will then be saved to a variable called auth and then exported to be used in the Signup.js file.

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";

const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_KEY,
  authDomain: "fir-auth-tutorial-15ee5.firebaseapp.com",
  projectId: "fir-auth-tutorial-15ee5",
  storageBucket: "fir-auth-tutorial-15ee5.appspot.com",
  messagingSenderId: "637624986163",
  appId: "1:637624986163:web:a1d6d50f2078b029961146",
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const auth = getAuth();

Importing the createUser and SignIn SDK.

We will import useNavigate function from react-router-dom and then save it to a navigate variable we will then import auth from our ../firebase.js file, then also import the createUserWithEmailAndPassword and the signInWithEmailAndPassword from firebase, these will be used called in both the handleSignUp and handleLogin functions respectively, and will both take in three arguments which will be auth, email and password. If we are able to successfully log in or signup we will then use the navigate function to navigate to our /home page. In the case of an error, we will use the SetError state hook to change the value of the error to true which will then make the error message show in our form field.

import React from "react";
import "./signup.css";
import { createUserWithEmailAndPassword } from "firebase/auth";
import { signInWithEmailAndPassword } from "firebase/auth";
import { auth } from "../firebase";
import { useNavigate } from "react-router-dom";
export default function Signup() {
  const [error, setError] = React.useState(false);
  const [toggle, setToggle] = React.useState(true);
  const [email, setEmail] = React.useState("");
  const [password, setPassword] = React.useState("");
  const navigate = useNavigate();
  const handleToggle = function () {
    setToggle((prevToggle) => !prevToggle);
  };
  const handleSignup = function (e) {
    e.preventDefault();
    createUserWithEmailAndPassword(auth, email, password)
      .then((userCredential) => {
        const user = userCredential.user;
        console.log(user);
        navigate("/home");
      })
      .catch((error) => {
        error ? setError(true) : setError(false);
      });};
  const handleSignIn = function (e) {
    e.preventDefault();
    signInWithEmailAndPassword(auth, email, password)
      .then((userCredential) => {
        const user = userCredential.user;
        console.log(user);
        navigate("/home");})
      .catch((error) => {
        error ? setError(true) : setError(false);
      });};
  return (
    <div className="signup">
      {toggle ? (
        <form onSubmit={handleSignup}>
          <input type="email" placeholder="email"
            onChange={(e) => setEmail(e.target.value)}/>
          <input type="password" placeholder="password"
            onChange={(e) =>setPassword(e.target.value)}
          />
          <button>Sign Up</button>
          <p style={{ color: "green" }} onClick={handleToggle}>
            Already have an account?</p>
          {error && <span>Error, Couldn't signUp</span>}
        </form>
      ) : (
        <form onSubmit={handleSignIn}>
          <input
            type="email"
            placeholder="email"
            onChange={(e) => setEmail(e.target.value)}/>
          <input
            type="password"
            placeholder="password"
            onChange={(e) =>setPassword(e.target.value)}
          />
          <button>Login</button>
          <p style={{ color: "green" }} onClick{handleToggle}>
            Don't have an account?</p>
          {error && <span>Error, Couldn't Login!</span>}
        </form>
      )}
    </div>
  );}

And that’s it. Now everything bug-free and in perfect working condition it should then look like this:

Conclusion

Firebase is a useful tool for developers looking to add secure and easy-to-use user authentication for their apps. It allows an effective way of authenticating your users and keeping their data secure, whether you are building a mobile application or a web application. It serves as a great choice for any developer wanting to add user authentication to their app.