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…