Anonymous Auth
Firebase Anonymous Authentication: give users state before they sign in, then upgrade cleanly when they do.
Firebase — anonymous auth
EXAMPLE
// ===== Why anonymous auth =====
// - Save user preferences before they sign up
// - Let users try features without an account
// - Cart persistence in e-commerce
// - Onboarding analytics with a stable id
// You get a real UID; security rules can scope data to that uid.
// ===== Enable =====
// Firebase Console -> Authentication -> Sign-in method -> Anonymous -> Enable
// ===== Sign in anonymously =====
import { getAuth, signInAnonymously, onAuthStateChanged } from 'firebase/auth';
const auth = getAuth();
await signInAnonymously(auth);
console.log(auth.currentUser?.uid); // permanent anonymous UID
// ===== Persistence across sessions =====
// The anonymous user is persisted in localStorage (web) or Keychain (mobile).
// The same UID will be there on next visit unless they clear storage or sign out.
// ===== Linking to a real provider =====
import { GoogleAuthProvider, linkWithPopup, EmailAuthProvider, linkWithCredential } from 'firebase/auth';
// Google:
const provider = new GoogleAuthProvider();
await linkWithPopup(auth.currentUser, provider);
// The UID stays the same. All data tied to that UID is now under the upgraded account.
// Email / password:
const cred = EmailAuthProvider.credential('a@x.io', 'pw');
await linkWithCredential(auth.currentUser, cred);
// ===== Watching state =====
onAuthStateChanged(auth, (user) => {
if (!user) return console.log('signed out');
console.log('uid', user.uid, 'isAnonymous', user.isAnonymous);
});
// ===== Security rules pattern =====
rules_version = '2';
service cloud.firestore {
match /databases/{db}/documents {
match /carts/{uid} {
allow read, write: if request.auth != null && request.auth.uid == uid;
}
// Optionally restrict anonymous to specific collections:
match /posts/{id} {
allow read: if true;
allow write: if request.auth != null && request.auth.token.firebase.sign_in_provider != 'anonymous';
}
}
}
// ===== Server-side acceptance =====
// On backend, verify the ID token; check provider:
import { getAuth } from 'firebase-admin/auth';
const decoded = await getAuth().verifyIdToken(token);
if (decoded.firebase.sign_in_provider === 'anonymous') {
// anonymous; rate-limit harder, restrict features
}
// ===== When to link + sign out =====
// - Link when the user signs up with a real provider
// - DO NOT sign out before linking; signing out abandons the anonymous account
// - If the user signs out then signs in differently, you LOSE the anon-side data
// ===== Cleanup =====
// Anonymous users persist until deleted. They count towards your user totals.
// Periodically reap inactive anonymous accounts:
// Cloud Function on a schedule: list users -> filter providers -> last activity -> delete
// ===== Patterns to internalise =====
// - Anonymous as the default for first-time visitors
// - Link before sign out to preserve user state
// - Security rules treat anonymous separately if you want to gate features
// - Periodic cleanup of inactive anonymous users
// ===== Pitfalls =====
// - Allowing anonymous users to write expensive data (DDoS risk)
// - Forgetting to upgrade rules to require non-anonymous for sensitive ops
// - Signing out an anon user without linking -> data orphaned forever
// - Treating UID stability as a security boundary (a new device = new anon UID)
Why it matters
Anonymous auth gives users a stable identity from first click. Wrap features in rules scoped by uid, link on sign-up to keep their data, and reap dormant anon accounts. The pattern is: give them state cheaply, ask for credentials only when there is a clear reason.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
import { signInAnonymously } from 'firebase/auth';
const { user } = await signInAnonymously(auth);
console.log('anonymous uid:', user.uid);
Try it Yourself »
Discussion
Loading…