0
0
FirebaseHow-ToBeginner · 4 min read

How to Protect Routes Using Firebase Auth: Simple Guide

To protect routes using Firebase Auth, check the user's authentication state before allowing access. Use onAuthStateChanged or hooks like useAuthState to detect if a user is signed in, and redirect or block access if not authenticated.
📐

Syntax

Use Firebase's onAuthStateChanged method to listen for authentication state changes. This method takes a callback that receives the current user or null if not signed in.

Example parts:

  • firebase.auth().onAuthStateChanged(user => { ... }): listens for user sign-in or sign-out.
  • user: the current user object if signed in, otherwise null.
  • Redirect or block routes based on whether user is null or not.
javascript
firebase.auth().onAuthStateChanged(user => {
  if (user) {
    // User is signed in, allow access
  } else {
    // User not signed in, redirect to login
  }
});
💻

Example

This example shows how to protect a route in a simple React app using Firebase Auth. It redirects users to the login page if they are not signed in.

javascript
import React, { useEffect, useState } from 'react';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
import { initializeApp } from 'firebase/app';
import { useNavigate } from 'react-router-dom';

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID"
};

initializeApp(firebaseConfig);

function ProtectedRoute({ children }) {
  const [loading, setLoading] = useState(true);
  const [user, setUser] = useState(null);
  const navigate = useNavigate();
  const auth = getAuth();

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      if (currentUser) {
        setUser(currentUser);
      } else {
        navigate('/login');
      }
      setLoading(false);
    });
    return () => unsubscribe();
  }, [auth, navigate]);

  if (loading) {
    return <div>Loading...</div>;
  }

  return user ? children : null;
}

export default ProtectedRoute;
Output
If user is signed in, the protected content renders; otherwise, user is redirected to /login.
⚠️

Common Pitfalls

  • Not waiting for the auth state to load before rendering routes can cause flickering or unauthorized access.
  • Forgetting to unsubscribe from onAuthStateChanged can cause memory leaks.
  • Not handling the null user state properly leads to errors or broken redirects.
javascript
/* Wrong: Not unsubscribing and no loading state */
useEffect(() => {
  onAuthStateChanged(auth, (user) => {
    if (!user) {
      navigate('/login');
    }
  });
}, []);

/* Right: Unsubscribe and handle loading */
useEffect(() => {
  const unsubscribe = onAuthStateChanged(auth, (user) => {
    if (!user) {
      navigate('/login');
    }
  });
  return () => unsubscribe();
}, []);
📊

Quick Reference

  • onAuthStateChanged: Listen for user sign-in/out.
  • Redirect: Send unauthenticated users to login.
  • Loading state: Show loading while checking auth.
  • Unsubscribe: Clean up listeners on unmount.

Key Takeaways

Always check Firebase Auth state before rendering protected routes.
Use onAuthStateChanged to listen for user sign-in status changes.
Redirect unauthenticated users to a login page to protect routes.
Manage loading state to avoid UI flicker during auth checks.
Unsubscribe from auth listeners to prevent memory leaks.