Connect your app
Firenook serves the same protocols on the same ports as the official emulators, so an app connects to it exactly as it would to them. This page covers what every platform has in common: how an SDK finds the emulators, which host and port to give it, and which project id to use. The platform pages after it have the code.
How an app finds the emulators
Section titled “How an app finds the emulators”There are two ways, and which one applies depends on where the code runs.
Client SDKs (web, Flutter, Android, Apple platforms, React Native) need one call per product, made once, before the app reads or writes anything:
| Platform | The calls, for Authentication, Firestore, Storage and Functions |
|---|---|
| Web, React Native | connectAuthEmulator, connectFirestoreEmulator, connectStorageEmulator, connectFunctionsEmulator |
| Flutter | useAuthEmulator, useFirestoreEmulator, useStorageEmulator, useFunctionsEmulator |
| Android, Apple platforms | useEmulator on each product’s instance |
Server code (the Admin SDKs and Google’s Cloud client libraries) reads
environment variables instead. Set them before the SDK starts, or run the
code with firenook emulators:exec, which sets them for you:
| Variable | With the default ports | Read by |
|---|---|---|
FIRESTORE_EMULATOR_HOST |
127.0.0.1:8080 |
Admin SDKs, Firestore libraries |
FIREBASE_AUTH_EMULATOR_HOST |
127.0.0.1:9099 |
Admin SDKs |
FIREBASE_STORAGE_EMULATOR_HOST |
127.0.0.1:9199 |
Admin SDKs for Node.js and Go |
STORAGE_EMULATOR_HOST |
http://127.0.0.1:9199 |
Cloud Storage libraries, and so the Python Admin SDK |
PUBSUB_EMULATOR_HOST |
127.0.0.1:8085 |
Pub/Sub libraries |
FIREBASE_EMULATOR_HUB |
127.0.0.1:4400 |
Tools that find the emulators |
GCLOUD_PROJECT |
The project id | Admin SDKs, Cloud libraries |
GOOGLE_CLOUD_PROJECT |
The project id | Admin SDKs, Cloud libraries |
GOOGLE_APPLICATION_CREDENTIALS |
A demo credentials file | SDKs that need credentials |
CLOUD_TASKS_EMULATOR_HOST |
127.0.0.1:9499 |
The Admin SDK’s task queues |
CLOUD_EVENTARC_EMULATOR_HOST |
http://127.0.0.1:9299 |
The Admin SDK’s Eventarc client |
emulators:exec sets the variables of the emulators that run, as the
official command does, the last two when Functions run, and writes the demo
credentials file. Write the hosts without http://, except the two that the
table shows with it. Your Functions need none of this: Firenook starts them
with the emulator hosts already set, the last two included.
Server SDKs has the details per
language.
Every emulator listens on the port firebase.json gives it under
emulators, or on the official default when it gives none. The ones an app
connects to:
| Emulator | Default port |
|---|---|
| Firestore | 8080 |
| Authentication | 9099 |
| Cloud Storage | 9199 |
| Cloud Functions | 5001 |
| Pub/Sub | 8085 |
| Eventarc | 9299 |
| Cloud Tasks | 9499 |
| Console (the Emulator UI port) | 4000 |
Every port, with the hub, logging and the Firestore WebSocket, is in Ports.
Which host to use
Section titled “Which host to use”Firenook listens on the loopback address unless you tell it otherwise, as the
official emulator does: Firestore, Auth, Storage and the other emulators on
127.0.0.1, and the hub and the console on ::1 as well. Use 127.0.0.1
rather than localhost: a client that tries ::1 first without falling
back cannot reach Firestore, Auth or Storage.
| Where the app runs | Host to use |
|---|---|
| The same machine: a browser, Node.js, the iOS Simulator | 127.0.0.1 |
| The Android emulator | 10.0.2.2, the emulator’s name for your machine |
| A phone, tablet or another computer on your network | Your machine’s network address, with Firenook started with --host 0.0.0.0 |
To reach Firenook from another device, make it listen on every interface:
npx firenook emulators:start --host 0.0.0.0It warns you before it starts:
Firenook: binding 0.0.0.0; the emulators have no authentication, so every service, the data and arbitrary Functions execution are reachable from any device that can reach this host.Take that literally, and only do it on a network you trust. firebase.json
can set the host instead, with "host": "0.0.0.0" on an emulator’s entry.
Firenook listens on one host for every emulator, so the host you set on one
entry applies to all of them, and two different hosts are an error:
Firenook: Unsupported host for auth: 0.0.0.0 differs from 192.168.1.50; the Firenook suite listens on one host (use --host or the same emulators.<name>.host everywhere).When Firenook listens on 0.0.0.0, the variables emulators:exec sets
still name 127.0.0.1, since that is how code on the same machine reaches
it.
Use the same project id
Section titled “Use the same project id”The app must use the project id Firenook runs with: the one in
.firebaserc, or the one you pass with --project. A demo- project id,
such as demo-shop, never reaches a real Firebase project, and the SDKs need
no real configuration for it:
- Any string works as the
apiKey, but the client SDKs want one to be there. - Cloud Storage’s default bucket is
<project id>.appspot.com, so a demo app setsstorageBucket: 'demo-shop.appspot.com'.
With a real project id, keep your app’s own configuration and add the connect calls after it. Products you do not point at an emulator still talk to Google.
If the ids differ, Firenook logs a warning (“Multiple projectIds are not
recommended in single project mode”), and the
console shows a banner that the app is using another project, with a
How to fix button. Data written without a signed-in user lands under the
other project id, where the console does not show it. Firestore requests
from a signed-in user fail with UNAUTHENTICATED: emulator JWT claims do not match this project, because the Auth emulator issues tokens for Firenook’s
own project.
The console’s Connect dialog
Section titled “The console’s Connect dialog”The console writes the connection code for you, with your ports, host and
project id filled in. Open the console (http://127.0.0.1:4000/console, or
press o in the terminal) and select Connect in the top bar. The dialog
lists the platforms down its side:
- Apps: Web, Flutter, Apple, Android
- Servers: Admin (Node), Python, Go, Java
- Configuration: Environment variables, and the
emulatorsblock offirebase.jsonwith the ports this run uses - Agents: the MCP server for a coding agent
The Host menu at the top switches the snippets between this machine,
the address you opened the console at (when that is another machine’s
address), 10.0.2.2 for the Android emulator, or a host you type. The
browser remembers your choice. A snippet leaves out a product that is not
running, so it never points at a port nothing listens on. For a demo-
project the snippet is complete and runs as printed; for a real project it
keeps your configuration and adds the connect lines.
The address names the platform, so a link opens the dialog on it:
http://127.0.0.1:4000/console?connect=android. The search box in the top
bar copies a snippet without opening the dialog: type snippet and pick
Copy the Web snippet, or another platform’s.
Platforms
Section titled “Platforms”- Web: the Firebase JS SDK in a browser app, with Vite and Next.js.
- Flutter: FlutterFire on Android, iOS and the web.
- Android: Kotlin and Java, the Android emulator and cleartext traffic.
- Apple platforms: Swift and Objective-C, the Simulator and devices.
- React Native: React Native Firebase, or the JS SDK in Expo.
- Server SDKs: the Admin SDKs for Node.js, Python, Go and Java, and Google’s Cloud client libraries.
Start with your app’s platform above, then run your tests against the same emulators.