Scaffold Firebase in a project using the Firebase MCP. Initialises Cloud Functions (TypeScript), Hosting, Firestore Rules, and the local emulator suite. Use when the user asks to "add Firebase", "set up Firebase", "scaffold Firebase", "init Firebase", or needs Functions and Hosting configured from scratch.
Set up Firebase in a project via #tool:firebase. Focuses on Cloud Functions and Hosting — the two most common Firebase features for web apps. Also supports Firestore Rules and other Firebase "Build" components. Configures the local emulator suite so the user can develop and test entirely offline.
See also: shai-firebase-function for Cloud Functions coding conventions and file-structure guidelines.
Do NOT use for:
shai-firebase-functionAt the start of each workflow step, output a progress indicator in bold blue:
🔹 Step M/N — {Step title}
where M is the current step number and N is the total number of steps in the workflow. This is mandatory for every step — never skip it.
Use #tool:vscode/askQuestions to ask the user:
Which Firebase features do you need?
Do you already have a Firebase project in the Firebase Console?
#tool:firebaseFunctions runtime:
Functions region (e.g. us-central1, europe-west1):
us-central1 and note it can be changed later in the functions config constants file.Use #tool:firebase for all Firebase operations. If the CLI is not available locally, install it:
npm install -g firebase-tools
Then authenticate:
firebase login
Use #tool:firebase to initialise the project. Select only the features the user requested in Step 1.
During the interactive prompts:
Functions, Hosting, Firestore Rules, and any other requested "Build" componentspublic (or the framework build output folder)firestore.rules (default)Use #tool:firebase to configure emulators for every selected feature.
Select emulators matching the enabled features:
Verify the firebase.json includes the emulators section:
{
"emulators": {
"functions": { "port": 5001 },
"hosting": { "port": 5000 },
"firestore": { "port": 8080 },
"ui": { "enabled": true, "port": 4000 },
},
}
After init, the CLI creates a functions/ directory. Adjust it to follow the conventions in references/project-structure.md:
functions/
├── src/
│ ├── index.ts ← re-exports all *.fn.ts functions
│ ├── config.ts ← region, runtime options, constants
│ ├── init.ts ← Firebase Admin SDK initialisation
│ ├── db.ts ← Firestore helpers / typed refs
│ └── services/ ← business logic (injected into functions)
├── .secret.local ← local secrets (gitignored)
├── package.json
└── tsconfig.json
Key actions:
src/config.ts with the chosen region:export const FN_REGION = "us-central1";
export const RUNTIME_OPTIONS = {
timeoutSeconds: 60,
memory: "256MiB" as const,
};
src/init.ts:/** Initialises the Firebase Admin SDK once. Imported by db.ts and other infra modules. */
import { initializeApp } from "firebase-admin/app";
export const app = initializeApp();
src/db.ts:import { getFirestore } from "firebase-admin/firestore";
import { app } from "./init";
export const db = getFirestore(app);
Add .secret.local to .gitignore (for the admin service account key)
Update src/index.ts to re-export functions:
// Re-export all cloud functions
// Add new functions here: export { myFunction } from "./my-function.fn";
Ensure functions/package.json includes emulator and deploy scripts:
{
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"start": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"emulators": "firebase emulators:start",
"emulators:export": "firebase emulators:export ./emulator-data",
},
}
Run the emulator to confirm everything works:
cd functions && npm run build && cd ..
firebase emulators:start
Confirm the Emulator UI is accessible at http://localhost:4000.
Present a summary to the user:
## Firebase Setup Complete
### Features enabled:
- [x] Cloud Functions (TypeScript)
- [x] Hosting
- [x] Firestore Rules
- [x] Local Emulator Suite
### Project structure:
src/fn/
├── index.ts — function re-exports
├── config.ts — region & runtime constants
├── init.ts — Admin SDK initialisation
├── db.ts — Firestore instance
└── services/ — business logic (empty, ready)
### Next steps:
- Create your first function with `shai-firebase-function`
- Run `firebase emulators:start` to develop locally
- Secrets are managed via CI/CD; see .secret.local for local dev
shai-firebase-function#tool:firebase for all Firebase operations — do not manually create firebase.json or .firebaserc. The Firebase MCP / CLI handles project linking, feature flags, and emulator config correctly.npx firebase-tools or a pinned version in devDependencies..secret.local for local development and inject secrets via CI/CD environment variables in production.config.ts and used by every function. Changing it later means redeploying all functions.emulators:export / emulators:import to persist local data across restarts if needed.