In this tutorial we’ll be using the Firebase Authentication service to setup user registration and authentication in a React application. Firebase simplifies the process of user authentication allowing you to focus on other parts of the development process.
Completed source code can be found on GitHub.
Let’s get started by creating our application using Create React App
and installing the Firebase and React Router dependencies by running the following commands:
npx create-react-app react-firebase-auth
cd react-firebase-auth
npm install firebase react-router-dom
Setup Firebase
Create a Firebase account and add a “New Project”.
Follow the prompts to complete the setup and you’ll end up here:
Add Firebase to your app using the web option (</>).
To complete the Firebase setup we need to specify an authentication method. There are a number of methods available but for this tutorial we’ll be using the email and password method. Navigate to “Authentication” -> “Sign-in Method” and change the “Email/Password” status setting to “Enabled”.
Firebase config
Create a new file in the following location – src/config.js
.
This file import’s the Firebase SDK and contains the Firebase configuration settings:
import firebase from "firebase/app";
import "firebase/auth";
const firebaseConfig = firebase.initializeApp({
apiKey: "AIzaSyBRnU-ukg1hajloAXYxmU_2wiKnwbNKDhA",
authDomain: "react-firebase-auth-6270e.firebaseapp.com",
databaseURL: "https://react-firebase-auth-6270e.firebaseio.com",
projectId: "react-firebase-auth-6270e",
storageBucket: "react-firebase-auth-6270e.appspot.com",
messagingSenderId: "83091629514",
appId: "1:83091629514:web:99702034755a934a5a9b33",
});
export default firebaseConfig;
Copy these setting from “Project Settings” -> “General” in the Firebase console.
Sign up form
Create a new file in the following location – src/components/SignUp.js
.
This component contains a sign up form so users can create accounts:
import React, {useState} from "react";
import { Redirect } from "react-router-dom";
import firebaseConfig from "../config";
const SignUp = () => {
const [currentUser, setCurrentUser] = useState(null);
const handleSubmit = (e) => {
e.preventDefault();
const { email, password } = e.target.elements;
try {
firebaseConfig.auth().createUserWithEmailAndPassword(email.value, password.value);
setCurrentUser(true);
} catch (error) {
alert(error);
}
};
if (currentUser) {
return <Redirect to="/dashboard" />;
}
return (
<>
<h1>Sign Up</h1>
<form onSubmit={handleSubmit}>
<label for="email">Email</label>
<input type="email" name="email" placeholder="Email" />
<label for="password">Password</label>
<input type="password" name="password" placeholder="Password" />
<button type="submit">Submit</button>
</form>
</>
);
};
export default SignUp;
On form submit we’re passing the email & password entered to the Firebase Auth createUserWithEmailAndPassword
method. If successful the browser will redirect to a dashboard page that contains content only visible to authenticated users. If the sign up fails and alert message describing the error is triggered.
Authentication
Create a new file in the following location – src/components/Auth.js
.
This component determines whether or not a user has been authenticated:
import React, { useEffect, useState } from "react";
import firebaseConfig from "../config.js";
export const AuthContext = React.createContext();
export const AuthProvider = ({ children }) => {
const [loading, setLoading] = useState(true);
const [currentUser, setCurrentUser] = useState(null);
useEffect(() => {
firebaseConfig.auth().onAuthStateChanged((user) => {
setCurrentUser(user);
setLoading(false);
});
}, []);
if (loading) {
return <p>Loading...</p>;
}
return (
<AuthContext.Provider value={{ currentUser }}>
{children}
</AuthContext.Provider>
);
};
Here we create a AuthContext
object which is used to share the currentUser status between our various components. onAuthStateChanged
is an observer for changes to the user’s sign-in state, this is triggered when user’s sign in or sign out.
Log in form
Create a new file in the following location – src/components/LogIn.js
.
This component contains the log in form so users can sign into their account:
import React, { useContext } from "react";
import { Redirect } from "react-router-dom";
import { AuthContext } from "./Auth";
import firebaseConfig from "../config.js";
const LogIn = () => {
const handleSubmit = (e) => {
e.preventDefault();
const { email, password } = e.target.elements;
try {
firebaseConfig.auth().signInWithEmailAndPassword(email.value, password.value);
} catch (error) {
alert(error);
}
};
const { currentUser } = useContext(AuthContext);
if (currentUser) {
return <Redirect to="/dashboard" />;
}
return (
<>
<h1>Log In</h1>
<form onSubmit={handleSubmit}>
<label for="email">Email</label>
<input type="email" name="email" placeholder="Email" />
<label for="password">Password</label>
<input type="password" name="password" placeholder="Password" />
<button type="submit">Submit</button>
</form>
</>
);
};
export default LogIn;
If the current user is already logged in they’ll get redirected to the dashboard. Otherwise we capture the form input on submit and send the details to the Firebase Auth signInWithEmailAndPassword
method.
Dashboard
Create a new file in the following location – src/components/Auth.js
.
This component contains content that can only be viewed by authenticated users:
import React, { useContext } from "react";
import { Redirect } from "react-router-dom";
import { AuthContext } from "./Auth";
import firebaseConfig from "../config.js";
const Dashboard = () => {
const { currentUser } = useContext(AuthContext);
if (!currentUser) {
return <Redirect to="/login" />;
}
return (
<div>
<h1>Welcome</h1>
<p>This is the dashboard, if you can see this you're logged in.</p>
<button onClick={() => firebaseConfig.auth().signOut()}>Sign out</button>
</div>
);
};
export default Dashboard;
If this page is accessed by a non-authenticated user the browser will re-direct to the login page. If the user is authenticated we display the private content. We’ve also included a button so users can sign out of their account.
Home page
Create a new file in the following location – src/components/Home.js
.
This component contains links to relevant pages based on the authentication status:
import React, { useContext } from "react";
import { Link } from "react-router-dom";
import { AuthContext } from "./Auth";
const Home = () => {
const { currentUser } = useContext(AuthContext);
return (
<>
<h1>Home</h1>
{currentUser ? (
<p>
You are logged - <Link to="/dashboard">View Dashboard</Link>
</p>
) : (
<p>
<Link to="/login">Log In</Link> or <Link to="/signup">Sign Up</Link>
</p>
)}
</>
);
};
export default Home;
At any location in the application we can check the status of currentUser
and display different content based on this status. Here we’ve provided a link to the private dashboard for authenticated users and log in / sign up links for non-authenticated users.
Pulling it all together in App.js
Modify the App.js
file to include the following:
import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Home from "./components/Home";
import Dashboard from "./components/Dashboard";
import LogIn from "./components/LogIn";
import SignUp from "./components/SignUp";
import { AuthProvider } from "./components/Auth";
const App = () => {
return (
<AuthProvider>
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/dashboard" component={Dashboard} />
<Route exact path="/login" component={LogIn} />
<Route exact path="/signup" component={SignUp} />
</Switch>
</Router>
</AuthProvider>
);
};
export default App;
You can now run npm start
to start the application and test out the registration and authentication process. Once the sign up form has been submitted you can browse to “Authentication” -> “Users” in the Firebase console to confirm registration was successful and manage user accounts.
You now know how to authenticate users in your React applications using Firebase. If you would like to learn more about Firebase Authentication I’d suggest checking out the official guide.
This article was originally published @ michaelburrows.xyz.