Choorai
Lv.2 Google

Firebase Auth Guide

Firebase Authentication is Google's free authentication service. It can be used for both web and mobile apps.

Why Firebase Auth?

  • Free tier: Unlimited MAU
  • Social login support for Google, Facebook, Apple, etc.
  • Email/password and phone number authentication
  • Integration with other Firebase services (Firestore, Storage)
  • Same API for mobile apps (Flutter, React Native)

1Firebase Project Setup

  1. Create a project at Firebase Console
  2. Click AuthenticationGet started
  3. Enable desired sign-in methods:
    • Email/Password
    • Google
    • GitHub (OAuth setup required)
  4. Project settings → General → Add web app
  5. Copy the Firebase configuration

2React App Integration

Terminal
npm install firebase

Environment Variables

.env.local
# .env.local
VITE_FIREBASE_API_KEY=xxx
VITE_FIREBASE_AUTH_DOMAIN=your-app.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-app
VITE_FIREBASE_STORAGE_BUCKET=your-app.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=xxx
VITE_FIREBASE_APP_ID=xxx

Firebase Initialization

lib/firebase.ts
// lib/firebase.ts
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';

const firebaseConfig = {
  apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
  authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
  projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
  storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
  appId: import.meta.env.VITE_FIREBASE_APP_ID,
};

const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);

3Email/Password Authentication

components/EmailAuth.tsx
// components/EmailAuth.tsx
import { useState } from 'react';
import {
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
} from 'firebase/auth';
import { auth } from '../lib/firebase';

export function EmailAuth() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [isLogin, setIsLogin] = useState(true);
  const [error, setError] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError('');

    try {
      if (isLogin) {
        await signInWithEmailAndPassword(auth, email, password);
      } else {
        await createUserWithEmailAndPassword(auth, email, password);
      }
    } catch (err: any) {
      setError(err.message);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
        className="w-full px-4 py-2 border rounded-lg"
        required
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password (min 6 characters)"
        className="w-full px-4 py-2 border rounded-lg"
        required
        minLength={6}
      />
      {error && <p className="text-red-500 text-sm">{error}</p>}
      <button
        type="submit"
        className="w-full py-2 bg-blue-600 text-white rounded-lg"
      >
        {isLogin ? 'Sign In' : 'Sign Up'}
      </button>
      <button
        type="button"
        onClick={() => setIsLogin(!isLogin)}
        className="w-full text-sm text-gray-600"
      >
        {isLogin ? "Don't have an account? Sign Up" : 'Already have an account? Sign In'}
      </button>
    </form>
  );
}

4Google Social Login

components/GoogleLogin.tsx
// components/GoogleLogin.tsx
import { signInWithPopup, GoogleAuthProvider } from 'firebase/auth';
import { auth } from '../lib/firebase';

const googleProvider = new GoogleAuthProvider();

export function GoogleLogin() {
  const handleGoogleLogin = async () => {
    try {
      const result = await signInWithPopup(auth, googleProvider);
      // User info in result.user
      console.log('Login successful:', result.user);
    } catch (error: any) {
      console.error('Login failed:', error.message);
    }
  };

  return (
    <button
      onClick={handleGoogleLogin}
      className="flex items-center gap-2 px-4 py-2 bg-white border rounded-lg"
    >
      <svg className="w-5 h-5" viewBox="0 0 24 24">
        <path
          fill="#4285F4"
          d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
        />
        <path
          fill="#34A853"
          d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
        />
        <path
          fill="#FBBC05"
          d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
        />
        <path
          fill="#EA4335"
          d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
        />
      </svg>
      Continue with Google
    </button>
  );
}

Info

You must first enable Google Sign-In in Firebase Console. Other providers like GitHub and Facebook can be added in a similar way.

5Auth State Management (Custom Hook)

Use onAuthStateChanged to detect changes in login state.

hooks/useAuth.ts
// hooks/useAuth.ts
import { useState, useEffect } from 'react';
import { User, onAuthStateChanged, signOut } from 'firebase/auth';
import { auth } from '../lib/firebase';

export function useAuth() {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      setUser(user);
      setLoading(false);
    });

    // Unsubscribe on component unmount
    return () => unsubscribe();
  }, []);

  const logout = async () => {
    await signOut(auth);
  };

  return {
    user,
    loading,
    isAuthenticated: !!user,
    logout,
  };
}

Global State with Context

contexts/AuthContext.tsx
// contexts/AuthContext.tsx
import { createContext, useContext, ReactNode } from 'react';
import { User } from 'firebase/auth';
import { useAuth } from '../hooks/useAuth';

interface AuthContextType {
  user: User | null;
  loading: boolean;
  isAuthenticated: boolean;
  logout: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | null>(null);

export function AuthProvider({ children }: { children: ReactNode }) {
  const auth = useAuth();

  return (
    <AuthContext.Provider value={auth}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuthContext() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuthContext must be used within AuthProvider');
  }
  return context;
}

// Usage in main.tsx
// <AuthProvider>
//   <App />
// </AuthProvider>

6Protected Route Implementation

components/ProtectedRoute.tsx
// components/ProtectedRoute.tsx
import { Navigate } from 'react-router-dom';
import { useAuthContext } from '../contexts/AuthContext';

interface ProtectedRouteProps {
  children: React.ReactNode;
}

export function ProtectedRoute({ children }: ProtectedRouteProps) {
  const { isAuthenticated, loading } = useAuthContext();

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

  if (!isAuthenticated) {
    return <Navigate to="/login" replace />;
  }

  return <>{children}</>;
}

// Usage example
// <Route
//   path="/dashboard"
//   element={
//     <ProtectedRoute>
//       <Dashboard />
//     </ProtectedRoute>
//   }
// />

User Profile Display

components/UserProfile.tsx
// components/UserProfile.tsx
import { useAuthContext } from '../contexts/AuthContext';

export function UserProfile() {
  const { user, logout, isAuthenticated } = useAuthContext();

  if (!isAuthenticated) {
    return null;
  }

  return (
    <div className="flex items-center gap-4 p-4 bg-white rounded-lg shadow">
      {user?.photoURL && (
        <img
          src={user.photoURL}
          alt={user.displayName || 'Profile'}
          className="w-12 h-12 rounded-full"
        />
      )}
      <div>
        <p className="font-bold">{user?.displayName || 'User'}</p>
        <p className="text-sm text-gray-600">{user?.email}</p>
      </div>
      <button
        onClick={logout}
        className="ml-auto px-4 py-2 bg-red-600 text-white rounded-lg"
      >
        Sign Out
      </button>
    </div>
  );
}

When Should You Choose Firebase Auth?

Firebase Auth Recommended

  • Already using Firebase ecosystem (Firestore, etc.)
  • Developing web + mobile simultaneously
  • Need unlimited free users
  • Google Sign-In is the primary method

Consider Alternatives

  • Need quick UI → Clerk
  • Next.js only → NextAuth
  • RBAC/Enterprise → Auth0
  • Need PostgreSQL → Supabase Auth

Next Steps

Last updated: February 22, 2026 · Version: v0.0.1

Send Feedback

Opens a new issue page with your message.

Open GitHub Issue