Firebase Auth with React
Google/GitHub sign-in, onAuthStateChanged listener, and route protection
What You’ll Build
After following this guide, you will have a working implementation of firebase auth with react in your project. Integrate Firebase Authentication into a React app with social login (Google, GitHub). Uses onAuthStateChanged for reactive auth state, a context provider pattern for app-wide access, and a ProtectedRoute component for guarding pages.
Use Cases & Problems Solved
- Protect routes so only authenticated users can access sensitive pages
- Allow users to sign up, log in, and manage their accounts securely
- Avoid storing raw passwords or building session management from scratch
Prerequisites
- Firebase project with Authentication enabled
- React 18+ app
- Enable Google/GitHub providers in Firebase Console
Step-by-Step Implementation
Install Firebase
The following snippet shows how to install firebase. Copy this into your project and adjust the values for your environment.
npm install firebase
Initialize Firebase
The following snippet shows how to initialize firebase. Copy this into your project and adjust the values for your environment.
// lib/firebase.js
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
Auth context provider
The following snippet shows how to auth context provider. Copy this into your project and adjust the values for your environment.
// context/AuthContext.jsx
import { createContext, useContext, useEffect, useState } from 'react';
import { onAuthStateChanged, signInWithPopup, GoogleAuthProvider, signOut } from 'firebase/auth';
import { auth } from '../lib/firebase';
const AuthContext = createContext();
export const useAuth = () => useContext(AuthContext);
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
setUser(user);
setLoading(false);
});
return unsub;
}, []);
const loginWithGoogle = () => signInWithPopup(auth, new GoogleAuthProvider());
const logout = () => signOut(auth);
return (
<AuthContext.Provider value={{ user, loading, loginWithGoogle, logout }}>
{!loading && children}
</AuthContext.Provider>
);
}
⚠️ Don’t Do This
❌ Not unsubscribing from onAuthStateChanged
useEffect(() => {
// Memory leak! No cleanup function
onAuthStateChanged(auth, (user) => setUser(user));
}, []);
✅ Always return the unsubscribe function
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => setUser(user));
return () => unsubscribe(); // Clean up on unmount
}, []);
Testing
Add these tests to verify your firebase auth with react implementation works correctly:
// __tests__/firebase.test.ts
import { describe, it, expect } from 'vitest';
describe('Firebase Auth with React', () => {
it('should handle successful authentication', async () => {
// Test the happy path
const result = await authenticate({ email: 'test@example.com', password: 'valid' });
expect(result.user).toBeDefined();
expect(result.error).toBeNull();
});
it('should reject invalid credentials', async () => {
const result = await authenticate({ email: 'test@example.com', password: 'wrong' });
expect(result.user).toBeNull();
expect(result.error).toBeDefined();
});
it('should handle missing fields', async () => {
const result = await authenticate({ email: '', password: '' });
expect(result.error).toBeDefined();
});
});
Verification
npm start
# Click 'Sign in with Google'
# Verify user display name appears
# Refresh the page — session should persist
# Click Sign Out and verify redirect Related Specs
Next.js Google OAuth Login
Complete Google OAuth flow with NextAuth.js, token handling, session management
Supabase Email/Password Auth
Sign up, sign in, password reset, and protected routes with Supabase Auth
GitHub OAuth with FastAPI
OAuth2 Authorization Code flow with token exchange and user profile fetch