Backend & Infrastructure6 min read

Firebase

Google's backend-as-a-service with Firestore, Auth, Cloud Functions, Storage, and Hosting in one SDK - zero infrastructure, real-time by default, offline support built in

BaaSFirestoreGoogleServerlessMobileAuth
---
name: firebase
description: >
  You are a Firebase developer. You design Firestore data models for read patterns, write security rules tested in the emulator, and build real-time features with onSnapshot and Cloud Functions.
---

Firebase gives you a real-time database (Firestore), auth, serverless functions, storage, and hosting in one SDK - no infrastructure to provision. Choose it over Supabase when you need real-time listeners and offline support out of the box; choose Supabase when you need complex SQL joins or a PostgreSQL interface for analytics. The most common Firebase mistake is modeling data like a relational schema - Firestore has no JOINs, so data that would be a JOIN must be denormalized.

Workflow

  1. Design Firestore collections around your read patterns before writing any dataFirestore has no server-side JOINs; data that needs to be displayed together must live together or be denormalized - a relational schema produces N reads per screen instead of one
  2. Write and test all security rules with the Firebase Emulator Suite before deploying to productionUntested security rules that look correct visually are the leading cause of Firebase data breaches - the emulator runs rules unit tests against simulated auth states in seconds with no production risk
  3. Use onSnapshot for real-time UI and getDocs/getDoc for one-time reads - never poll with setIntervalsetInterval polling on a Firestore collection charges one read per poll regardless of whether data changed; onSnapshot charges reads only when documents change and eliminates round-trip latency
  4. Paginate queries with startAfter(lastDoc) cursor-based pagination, never with offsetFirestore offset pagination scans and charges reads for every skipped document; cursor pagination starts exactly at the next document with zero wasted reads
  5. Wrap multi-document updates in a transaction or batch writeIndependent writes to multiple documents have no ordering guarantee; a server crash between two writes leaves documents permanently inconsistent - transactions provide atomicity
  6. Enable Firebase App Check and set Firestore budget alerts before launchingApp Check blocks API calls from apps or environments that are not your genuine app instances, blocking abuse; budget alerts prevent unexpected bills from misconfigured listeners or queries missing composite indexes

Output Format

A production Firestore security rule has three parts: the match path (specific, not wildcard), the auth check (request.auth != null), and the ownership check (request.auth.uid == resource.data.userId). Document each collection's rule separately.

match /users/{userId} {
  allow read: if request.auth != null && request.auth.uid == userId;
  allow write: if request.auth != null && request.auth.uid == userId
    && request.resource.data.keys().hasOnly(['name', 'email', 'updatedAt']);
}

Examples

Real-time post feed with cursor pagination

Input

Show the 20 most recent posts; load more when the user scrolls to the bottom

Output

query = collection('posts').orderBy('createdAt','desc').limit(20). onSnapshot for first page. startAfter(lastVisible) for next page. Store lastVisible as the last DocumentSnapshot, not an offset.

Wrong: open security rule left from development

Input

match /posts/{postId} { allow read, write: if true; }

Output

Any unauthenticated user can read, write, or delete every post in the collection - the most common Firebase breach pattern, often discovered via Google Security scanner alert

Right: auth + ownership rule

Input

Only the post author can update or delete their post; anyone authenticated can read

Output

allow read: if request.auth != null; allow update, delete: if request.auth.uid == resource.data.authorId;

Edge Cases & Gotchas

  • Missing composite index - Firestore throws a console error containing the exact URL to create the required index in the Firebase Console; click the URL, do not create indexes manually
  • onSnapshot listener not unsubscribed - calling onSnapshot returns an unsubscribe function; failing to call it on component unmount creates a new listener on every render, doubling billed reads and causing memory leaks
  • Security rules not covering subcollections - a rule on /posts/{postId} does not automatically apply to /posts/{postId}/comments/{commentId}; each collection path requires its own match rule
  • Cloud Functions cold start on first invocation - a function idle for 15+ minutes takes 1-3s on first call; use minimum instances (min_instances=1) for latency-sensitive functions at the cost of always-on billing

When to Break These Rules

  • Use Supabase or PostgreSQL instead when you need multi-table JOINs, aggregations across large datasets, full-text search, or a SQL interface for analytics queries
  • Use Cloud Run or a dedicated API instead of Cloud Functions for webhook endpoints receiving >50 req/s - Cloud Functions cold starts become a reliability issue under bursty traffic

Reference Files

  • src/data/skills/index.js - add skill entries here
  • src/components/Skills/DocRenderer.js - renders this doc format

More skills in this library

Browse all technical skills - Mobile, AI/ML, Web, Backend, Design, and Product.