codingstairs
NotesEDULifeContact
⌕Search⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

Get in touch

Send without signing in. Add your email if you'd like a reply.

  • Leave a message anonymously →
  • ✉ warragon112@gmail.com
  • KakaoTalk Open Chat ↗

© 2026 codingstairs

  • Notes
  • EDU
  • Search
  • Life
  • Contact
  • Legal
  • RSS
  • GitHub
Notes›cloud

Firebase Local Emulator Suite — Running a Firebase Bundle on a Laptop

Published 2026-04-28· Updated 2026-05-18·0 views

Firebase Local Emulator Suite — Running a Firebase Bundle on a Laptop

Firebase started as a small startup in 2011 and was acquired by Google in 2014. Being a managed-first service, "no way to run it locally" was the right answer for a long time, but in March 2020 the picture changed when Firebase Local Emulator Suite reached GA.

1. About the Suite

The Firebase Local Emulator Suite ships inside the Firebase CLI (firebase-tools) as a bundle of local emulators. Nine emulators running on a Java VM boot in a single process, all visible via a single Web UI (default port 4000).

Emulator Default port Emulates
Authentication 9099 Firebase Auth (email · OAuth · OTP · MFA).
Cloud Firestore 8080 NoSQL document DB.
Realtime Database 9000 JSON tree DB.
Cloud Storage 9199 Object storage (not S3 compatible).
Cloud Functions 5001 Serverless functions.
Cloud Pub/Sub 8085 Message queue.
Eventarc 9299 CloudEvents routing.
Hosting 5000 Static sites.
Firebase Extensions (per ext) Extension packages.

The most important fact — FCM (Cloud Messaging) is not on this list. Firebase officially does not provide an emulator. The reason is simple — FCM has to traverse real device tokens and Google's push infrastructure, so simulation has no meaning. The "FCM emulators" floating around the internet are all unofficial wrappers or HTTP mocks.

2. One process, many ports

firebase emulators:start boots them all. Each emulator listens on its own port. SDKs auto-route to the emulator when env vars (FIRESTORE_EMULATOR_HOST · FIREBASE_AUTH_EMULATOR_HOST) are set, so no code changes are needed.

3. Persistence · Web UI

By default everything is in memory and disappears at exit. With --export-on-exit ./data + --import ./data, data exports on exit and imports on start. Alternatively, mount the emulator cache directory as a volume.

The Web UI (default port 4000) — adding a user directly in the Authentication tab issues an ID token immediately. The Firestore tab lets you add, edit, and delete documents directly. The fastest path for debugging the "API call → DB change" flow.

Firestore Security Rules — Mounting firestore.rules makes the emulator apply those rules. Denied SDK calls log the precise reason. The standard way to do regression tests for rules before production deploys.

4. Directly on the host

npm i -g firebase-tools
firebase init emulators
firebase emulators:start

firebase init emulators creates the emulator section of firebase.json, with an interactive selection of which emulators to enable.

5. Docker container

There is no official Docker image; the community image is the de facto standard.

services:
  firebase:
    image: andreysenov/firebase-tools:13.x
    user: node
    working_dir: /home/node
    command:
      - firebase
      - emulators:start
      - --project=demo
      - --only=auth,firestore,storage,functions
    ports:
      - "4400:4400"   # UI (default 4000)
      - "9099:9099"   # Auth
      - "8085:8085"   # Firestore
    volumes:
      - ./firebase.json:/home/node/firebase.json:ro

Image around 500 MB. First boot takes 30~60 seconds for emulator JAR download + Java startup.

6. SDK calls

Node.js (firebase-admin) — Auto-routes when env vars are set:

export FIREBASE_AUTH_EMULATOR_HOST=localhost:9099
export FIRESTORE_EMULATOR_HOST=localhost:8085
export FIREBASE_STORAGE_EMULATOR_HOST=localhost:9199
export GOOGLE_CLOUD_PROJECT=demo
import { initializeApp } from "firebase-admin/app";
import { getFirestore } from "firebase-admin/firestore";

initializeApp({ projectId: "demo" });
await getFirestore().collection("users").add({ name: "test-user" });

Web client (firebase) — Env vars are not auto-detected; call explicitly:

import { initializeApp } from "firebase/app";
import { connectAuthEmulator, getAuth } from "firebase/auth";
import { connectFirestoreEmulator, getFirestore } from "firebase/firestore";

const app = initializeApp({ projectId: "demo", apiKey: "fake-api-key" });
connectAuthEmulator(getAuth(app), "http://localhost:9099");
connectFirestoreEmulator(getFirestore(app), "localhost", 8085);

7. Limitations

No FCM — Verify server-side send calls separately with an HTTP mock like WireMock.

Firebase Hosting SSR — Partially supported. Some constraints when integrating with Functions.

Cloud Storage download URL — The URL the emulator issues differs in form from production. Patterns that store URLs in the DB need environment branching.

Performance Monitoring · Crashlytics · Remote Config — No emulator at all. Verify only in production.

App Check · App Hosting — Partial or no support. Check the official matrix.

Java dependency — JDK inside the container makes the image heavy (~500 MB+). Memory is also around 500 MB.

Single-instance assumption — One PC, one run. Sharing across teams requires a separate host.

8. Using in CI

- run: docker compose up -d firebase
- run: |
    until curl -sf http://localhost:4400 >/dev/null; do sleep 2; done
- run: pnpm test

Polling for emulator readiness before tests is the key. Otherwise the first call hits ECONNREFUSED.

Closing thoughts

The most-searched gotcha for the Firebase Emulator Suite is that 9 of 9 minus FCM is the actual coverage. Setting env vars makes SDKs auto-route, so code changes are zero. Handling readiness polling well in CI makes it a standard channel for integration tests.

Next

  • api-mocking-wiremock

Firebase Emulator Suite · Connect & Prototype · andreysenov/firebase-tools · FCM official (no emulator) for reference.

More in cloud

All in this category →
  • title template single source — don''t let children stamp the site name
  • GitHub Pages — host a repo as a static site
  • Replit — Browser-based dev + deploy in one place
  • HTTP API Mocking — WireMock · MockServer · Prism · MSW
  • Supabase Self-Hosted — Packing a BaaS into One Postgres Pot
  • LocalStack and MiniStack — Emulating AWS Locally