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

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…