Firebase remains one of the quickest paths to a production-grade backend in 2026 — Firestore, Auth, Storage, and Cloud Functions under one project umbrella. The Modular SDK (v10+) completed the shift to tree-shakeable, function-based imports, and the Emulator Suite makes local development safe and fast. This guide gets a new project to a secure, production-ready baseline.
What changed in 2026
- Modular SDK v10 is the only recommended path; the
compat layer is in maintenance mode.
- App Check is effectively required for any public app — it verifies client authenticity using device attestation (reCAPTCHA v3, Play Integrity, App Attest).
- Firestore Data Connect (preview) is a GraphQL-over-Firestore layer aimed at enterprise use — interesting to watch, not yet the default.
- Firebase Extensions catalog has grown; many common patterns (email triggers, image resizing) are one-click installs.
Project setup
npm install -g firebase-tools
firebase login
firebase init
firebase init prompts you to pick services (Firestore, Functions, Hosting, etc.), sets up firebase.json, and downloads emulator binaries. Select "Emulators" to enable local testing.
Install the SDK:
npm install firebase
Initialize in code:
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import { getAuth } from 'firebase/auth';
const app = initializeApp({
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
});
export const db = getFirestore(app);
export const auth = getAuth(app);
Connecting to the Emulator Suite
import { connectFirestoreEmulator } from 'firebase/firestore';
import { connectAuthEmulator } from 'firebase/auth';
if (process.env.NODE_ENV === 'development') {
connectFirestoreEmulator(db, 'localhost', 8080);
connectAuthEmulator(auth, 'http://localhost:9099');
}
Start emulators with firebase emulators:start. The Emulator UI at localhost:4000 lets you browse data, trigger auth events, and inspect function logs.
Firestore CRUD with the Modular SDK
import { collection, addDoc, getDocs, query, where, orderBy } from 'firebase/firestore';
// Write
const docRef = await addDoc(collection(db, 'posts'), {
title: 'Hello',
authorId: auth.currentUser.uid,
createdAt: serverTimestamp(),
});
// Read with a filter
const q = query(
collection(db, 'posts'),
where('authorId', '==', auth.currentUser.uid),
orderBy('createdAt', 'desc'),
);
const snapshot = await getDocs(q);
const posts = snapshot.docs.map((d) => ({ id: d.id, ...d.data() }));
Firestore Security Rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId} {
allow read: if request.auth != null;
allow create: if request.auth.uid == request.resource.data.authorId;
allow update, delete: if request.auth.uid == resource.data.authorId;
}
}
}
Deploy rules: firebase deploy --only firestore:rules. Test rules locally with the Emulator or the Rules Playground in the Firebase console.
Firebase vs Supabase (2026)
| Dimension |
Firebase |
Supabase |
| Database model |
NoSQL (Firestore) |
Relational (Postgres) |
| Offline sync |
Native (Firestore) |
Via Realtime (limited) |
| SQL queries |
No |
Full SQL |
| Self-host |
No |
Yes |
| Mobile SDKs |
Excellent (iOS, Android) |
Good, improving |
| Serverless functions |
Cloud Functions (Node/Python) |
Edge Functions (Deno) |
How to start
- Create a project at console.firebase.google.com.
firebase init — select Firestore, Auth, Emulators at minimum.
- Write Security Rules before any production data lands.
- Enable App Check under "App Check" in the console.
- Use Modular SDK imports throughout; avoid the
compat path.
Common mistakes
Opening Firestore with allow read, write: if true; during prototyping and forgetting to lock it down. Use if request.auth != null as the minimum and ship proper rules before launch.
Querying without indexes. Compound queries (where + orderBy on different fields) require composite indexes. The Firestore emulator logs the index-creation link when it detects a missing index.
Bundling the full Firebase SDK. With the Modular SDK, import only firebase/firestore and firebase/auth, not firebase/app + everything. Bundle analyzers expose over-imports quickly.
Not testing Security Rules. The firebase-admin test helper (@firebase/rules-unit-testing) lets you assert that rules block what they should — write at least a few unit tests.
What to skip
- The Realtime Database — Firestore supersedes it for new projects; RTDB lacks Security Rules parity and has a different data model.
- Firebase Hosting for server-rendered apps — it suits static sites and SPAs; for SSR at scale, Cloud Run or another container host is more flexible.
- Compat imports —
import firebase from 'firebase/compat/app' brings the full legacy bundle; switch to modular imports.
FAQ
Is the Firebase API key a secret?
No — it is a public project identifier. Security comes from Firestore/Storage Security Rules and App Check, not from keeping the key private.
How do I handle server-side Firebase in Node.js?
Use the firebase-admin SDK with a service account JSON. It bypasses Security Rules (intentionally), so scope what server code does carefully.
How do I paginate large Firestore collections?
Use startAfter(lastDoc) with a limit() clause — cursor-based pagination. Offset pagination is not natively supported in Firestore.
Can I use Firebase Auth with a custom backend?
Yes — verify the Firebase ID token server-side with admin.auth().verifyIdToken(token). The decoded token includes uid and custom claims.
Where to go next