# Emulators and CI Deploys — Firebase

Source: https://www.skillbyai.com/en/firebase/pr-ci

> Test locally, deploy automatically.

## From laptop to production

During development, point the SDKs at the **Emulator Suite** with `connectFirestoreEmulator`, `connectAuthEmulator`, `connectStorageEmulator` and `connectFunctionsEmulator`, and seed data with `--import` / `--export-on-exit`. In CI, run unit and rules tests inside `firebase emulators:exec`, then deploy with the Firebase CLI authenticated through a Google Cloud **service account** (for example via workload identity federation or `GOOGLE_APPLICATION_CREDENTIALS`) rather than a personal login; legacy CI tokens are deprecated, so check the docs. Deploy rules, indexes, functions and hosting from version control so production always matches the repository.

## Local wiring and a CI script

TypeScript and Firebase CLI (shown, not run).

```bash
# src/firebase.ts (development only)
# if (location.hostname === "localhost") {
#   connectAuthEmulator(auth, "http://127.0.0.1:9099");
#   connectFirestoreEmulator(db, "127.0.0.1", 8080);
#   connectStorageEmulator(storage, "127.0.0.1", 9199);
# }

# local development with saved seed data
firebase emulators:start --import=./seed --export-on-exit

# CI: test against emulators, then deploy with a service account
npm ci
firebase emulators:exec --only firestore,auth,storage "npm test"
npm run build
firebase deploy --only firestore:rules,firestore:indexes,storage,functions,hosting \
  --project production --non-interactive
```

## Rules deploy with code

Keep `firestore.rules` and `storage.rules` in the repository and deploy them in CI, never by editing in the console, so every change is reviewed and tested.

**Quiz:** How should a CI pipeline authenticate the Firebase CLI?

- [ ] With the public web API key
- [ ] With a developer's personal password
- [x] With a Google Cloud service account
- [ ] It needs no authentication

*Answer:* With a Google Cloud service account. Service accounts are auditable and revocable.
