Skip to content
React+Firebase
Stack Integration

React + Firebase Integration Guide

Firebase with React covers auth, Firestore real-time data, and Cloud Functions — the full backend without managing servers.

Use Cases
  1. Firebase Auth with React context for session management
  2. Firestore real-time listeners in React components
  3. Cloud Functions triggered by Firestore writes
  4. Firebase Storage for user-uploaded files
Implementation

Initialize Firebase once in a module, export the app, auth, and db instances. Use onSnapshot for real-time Firestore listeners — unsubscribe in useEffect cleanup to avoid memory leaks. Firestore security rules are the equivalent of RLS — write them before going to production.

In detail

How the pieces connect

Firebase runs almost entirely in the browser. You call initializeApp(config) once, then getAuth(), getFirestore(), and getStorage() hand back singletons your React tree shares. The Firebase JS SDK opens a persistent WebSocket to Firestore, so onSnapshot pushes document changes straight into React state — no polling, no REST round-trips. The standard pattern is an auth context: a top-level provider subscribes with onAuthStateChanged, holds the User (or null) in state, and gates routes. Writes go directly from the client to Firestore; there is no API layer of your own. The only server-side code is Cloud Functions, deployed separately and invoked either over HTTPS (httpsCallable) or as background triggers like onDocumentWritten. Knowing what runs where matters: the config object and Firestore rules are public, so the security boundary lives in rules and Function checks, not in your bundle.

Production gotchas

The most common leak is forgetting to unsubscribe. onSnapshot returns an unsubscribe function — return it from useEffect cleanup, or listeners stack on every re-render. React 18 Strict Mode mounts effects twice in dev, which surfaces missing cleanup early; treat the double-fire as a feature. Auth state is not known on first paint: onAuthStateChanged fires asynchronously, so guard routes on an explicit loading flag, not on user === null, or you will flash the login screen for signed-in users. Firestore bills per document read, and a broad onSnapshot on a large collection re-reads every changed doc — scope queries with where/limit and paginate. Cloud Functions cold-start on first invocation after idle; keep dependencies lean and set minInstances for latency-sensitive callables. Composite queries throw failed-precondition until you create the index the error links to.

Security considerations

Because clients write to Firestore directly, security rules are your access control, not an optional add-on. Write them as the equivalent of row-level rules: match documents by path and assert on request.auth.uid, e.g. allow a user to read/write only docs where resource.data.ownerId == request.auth.uid. Validate shape and types in rules too — clients can send any payload, so check request.resource.data fields before allowing a write. Never trust data computed in the browser for anything sensitive (roles, prices, totals); recompute or verify it in a Cloud Function or in rules. The Firebase config keys in your bundle are identifiers, not secrets, and are safe to expose — but service-account credentials and any third-party API keys belong in Functions, set via environment config, never in client code. Test rules with the emulator before deploying; an open allow read, write: if true is the single most common breach in Firebase apps.

When this combo fits — and when it doesn't

React plus Firebase fits products that are real-time and user-centric: dashboards, chat, collaborative tools, internal apps, MVPs that need auth, data, and file storage without a backend team. I built Callidus, a clinic SaaS, on exactly this stack — React on the front, Firebase for auth and data — and shipping without a server layer removes the coordination overhead of an agency route. It fits less well when you need heavy relational joins, complex transactions across many entities, or SQL reporting — Firestore's query model is deliberately limited (no joins, no OR across fields without workarounds, no aggregate GROUP BY beyond count/sum/average). Per-read billing also punishes analytics-heavy reads. If your data is highly relational or you need full-text search, pair Firebase with a purpose-built service or reach for a SQL backend instead of fighting the document model.

Other integration guidesView all →
Related

Need this built?