iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Auth Intro

Firebase Auth handles signup, login, OAuth, MFA, and session management for web and mobile. ID tokens carry user identity through your services; Firestore rules verify them automatically.

Email/password + Google OAuth + custom claims

EXAMPLE
// 1) Initialise
import { initializeApp } from 'firebase/app';
import {
    getAuth,
    createUserWithEmailAndPassword,
    signInWithEmailAndPassword,
    signInWithPopup,
    GoogleAuthProvider,
    sendPasswordResetEmail,
    sendEmailVerification,
    onAuthStateChanged,
    signOut,
    updateProfile,
} from 'firebase/auth';

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

// 2) Sign up with email + password
async function signup(email, password, displayName) {
    const { user } = await createUserWithEmailAndPassword(auth, email, password);
    await updateProfile(user, { displayName });
    await sendEmailVerification(user);
    return user;
}

// 3) Log in
async function login(email, password) {
    try {
        const { user } = await signInWithEmailAndPassword(auth, email, password);
        return user;
    } catch (e) {
        // Common error codes:
        //   auth/invalid-credential
        //   auth/too-many-requests
        //   auth/user-disabled
        throw new Error(humanise(e.code));
    }
}

// 4) Google OAuth (popup or redirect)
async function googleLogin() {
    const provider = new GoogleAuthProvider();
    provider.addScope('email');
    const result = await signInWithPopup(auth, provider);
    return result.user;
}

// 5) Listen for auth state
const unsub = onAuthStateChanged(auth, (user) => {
    if (user) {
        store.dispatch({ type: 'AUTH', user: { uid: user.uid, email: user.email } });
    } else {
        store.dispatch({ type: 'LOGOUT' });
    }
});
// Call unsub() on app teardown.

// 6) Get the ID token (JWT) — pass to your backend
const token = await auth.currentUser.getIdToken();
fetch('/api/me', { headers: { Authorization: `Bearer ${token}` } });

// Force a refresh — after custom claims change server-side
await auth.currentUser.getIdToken(true);

// 7) Password reset
await sendPasswordResetEmail(auth, 'user@example.com');

// 8) Sign out
await signOut(auth);

// 9) Custom claims — server-side via Admin SDK
import { getAuth as adminAuth } from 'firebase-admin/auth';
await adminAuth().setCustomUserClaims(uid, { role: 'admin', org: 'acme' });
// Client must call getIdToken(true) before claims take effect.

// 10) MFA — TOTP (Firebase Auth)
import { multiFactor, TotpMultiFactorGenerator, TotpSecret } from 'firebase/auth';

const totpSecret = await TotpMultiFactorGenerator.generateSecret(multiFactor(user));
// Show QR / secret to user; once they enter the verification code:
const assertion = TotpMultiFactorGenerator.assertionForEnrollment(totpSecret, code);
await multiFactor(user).enroll(assertion, 'Authenticator');

// 11) Anonymous auth (good for guest checkout)
import { signInAnonymously, linkWithCredential, EmailAuthProvider } from 'firebase/auth';

const anon = await signInAnonymously(auth);
// Later, when the user signs up:
await linkWithCredential(anon.user, EmailAuthProvider.credential(email, password));

// 12) Backend verification — never trust the client
import { getAuth as serverAuth } from 'firebase-admin/auth';
app.post('/api/protected', async (req, res) => {
    const idToken = req.headers.authorization?.replace('Bearer ', '');
    try {
        const decoded = await serverAuth().verifyIdToken(idToken);
        req.uid    = decoded.uid;
        req.claims = decoded;
    } catch {
        return res.status(401).end();
    }
    // ... continue ...
});

// 13) Security rules use the same JWT
rules_version = '2';
service cloud.firestore {
    match /databases/{db}/documents {
        match /users/{uid} {
            allow read, write: if request.auth.uid == uid;
        }
        match /admin/{doc=**} {
            allow read, write: if request.auth.token.role == 'admin';
        }
    }
}

// 14) Best practices
//   • Always verify ID tokens on the backend — never trust the UID from the client
//   • Force email verification before sensitive actions (refunds, profile changes)
//   • Use rate-limit + bot protection on signup forms
//   • Pair with App Check for client-integrity on hostile traffic
//   • Custom claims for roles + org membership; Firestore rules for fine-grained authz

Why it matters

Firebase Auth + custom claims + Firestore rules is the “authenticate once, authorise everywhere” trifecta. The ID token flows through every request and the database rules read it without an extra lookup.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
import { getAuth, onAuthStateChanged } from 'firebase/auth';
const auth = getAuth(app);
onAuthStateChanged(auth, user => {
    console.log(user ? 'signed in as ' + user.email : 'signed out');
});
Try it Yourself »

Discussion

Loading…