Use AI to Pre-Flight Your Firebase Deploy

A 10-minute AI audit of firebase.json before you ship: rewrite order, function regions, cache headers, and preview-channel testing.

The painful Firebase deploys are the ones that succeed silently. The CLI prints a green URL, but a rewrite is mis-ordered, a Cloud Function drifted to us-central1, or an HTML file is now cached for a year behind a CDN you cannot purge. These bugs ship green and surface hours later. AI catches them before you push, because firebase.json is small, declarative, and its failure modes are well documented. Below is a checklist you can run through Claude Opus 4.7 or GPT-5.5 in about 10 minutes.

TL;DR

  • Paste your full firebase.json plus your functions/ entry file into Claude or ChatGPT and run the structured audit prompt below. Vague context produces vague audits.
  • The five high-yield checks: rewrite ordering (specific paths before **), function region consistency, correct public directory, cache headers (long+immutable for fingerprinted assets, short for HTML), and rewrite-to-function name matching.
  • Deploy to a preview channel first with firebase hosting:channel:deploy, smoke-test the flagged routes, then promote. Preview channels are free and expire after 7 days by default.
  • Demand fixes as drop-in diffs, not prose. If the AI returns “you should consider,” it is guessing.

Why firebase.json is the right thing to audit

Nearly every Hosting regression traces back to one of five blocks in firebase.json: rewrites, redirects, headers, public, and the function bindings. The config is declarative and only a few hundred lines, which is exactly the shape an LLM reasons about reliably. Unlike a firebase deploy --dry-run, which only validates JSON syntax and resolvable function names, an AI reading the file can flag semantic errors: rules in the wrong order, a cache directive on the wrong path, a region that silently fell back to the default.

This is for anyone deploying Firebase Hosting more than once a week, especially Astro or Next.js teams routing through firebase.json rewrites to Cloud Functions or Cloud Run. Solo devs without a staging environment get the most value, because the AI audit is the staging step.

The five checks that matter

1. Rewrite ordering

Firebase Hosting applies the first rewrite rule whose pattern matches the request and stops there (Hosting config docs). So a catch-all ** placed above a specific route swallows that route forever:

"rewrites": [
  { "source": "/api/**", "function": "api" },
  { "source": "**", "destination": "/index.html" }
]

If those two entries are flipped, every /api/* request resolves to index.html and your function is never reached. Hosting also only applies a rewrite when no static file matches the path first, so a stray file in public/ can shadow a rule entirely. Ask the AI to confirm the order goes most-specific to least-specific, top to bottom.

2. Function region consistency

A 2nd-gen Cloud Function with no explicit region falls back to us-central1. Firebase’s own docs recommend setting an explicit region rather than relying on the default, which can change (Cloud Functions locations). When half your functions are pinned to asia-northeast1 and one new function silently lands in us-central1, a rewrite chain that hops between them adds a cross-region round trip on every call. The symptom reads as “the function got slow,” but it is geography. Pin the region in code:

const { setGlobalOptions } = require("firebase-functions/v2");
setGlobalOptions({ region: "asia-northeast1" });

Note: as of June 2026, setGlobalOptions does not always apply to Firestore-triggered functions, which can still initialize in us-central1. Set the region explicitly on those triggers too.

3. The public directory

If your build output lands in dist/ (Astro, Vite) but public in firebase.json is set to out/ (Next.js export) or build/, the CLI happily uploads the wrong folder. The deploy succeeds and the site serves your previous build. This is the single most common “why are my changes not live” bug. Have the AI cross-check public against the actual output path in your build tooling.

4. Cache headers

Firebase Hosting honors your Cache-Control headers literally, and there is no global purge button. A bad header is fixed only by redeploying corrected headers and waiting out the TTL at every CDN edge (Manage cache docs). The rule of thumb as of June 2026:

Asset typeRecommended Cache-ControlWhy
Fingerprinted JS/CSS/fonts (app.9f3a1.js)public, max-age=31536000, immutableURL changes when content changes, so a 1-year cache is safe
Images with content hashespublic, max-age=31536000, immutableSame fingerprinting logic
HTML / index.htmlpublic, max-age=300, s-maxage=600 or no-cacheThe shell must update within minutes, not a year
service-worker.js, manifest.jsonno-cacheMust always revalidate

The classic outage: a wildcard max-age=31536000 rule intended for assets also matches index.html, freezing the navigation shell for a year. Ask the AI to list every path each header rule matches and flag any HTML caught by a long-lived rule.

5. Rewrite-to-function binding

functions/index.js exports ogImage, but a rewrite points to og-image. The deploy passes syntax validation and the route returns a silent 404. This is why pasting the function entry file alongside firebase.json matters: without it, the AI cannot verify the binding name exists.

Step by step

  1. Paste firebase.json plus your functions/ entry file into the AI with a one-line project description, e.g. “Astro static site with two Cloud Functions for OG image generation and a contact form, deployed to asia-northeast1.”
  2. Run the structured audit prompt:
Audit this firebase.json for deploy-time risks. Check:
- Rewrite rule order (specific paths before catch-all **)
- Function region consistency (all functions same region unless intentional)
- public directory matches my build output (state your build tool)
- Headers: long+immutable for fingerprinted assets, short/no-cache for HTML
- Redirects: any loops, any conflicting with rewrites
- Rewrite-to-function binding: each function name matches a real export

For each finding return: blocker | warning | nit, the exact line, and a
drop-in diff that fixes it. No prose fixes.
  1. For every finding, accept only a code block you can paste, never “you should consider.”
  2. Apply the diffs and re-run the audit on the patched file. It should now return zero blockers. If new issues appear, the AI may be hallucinating. Push back: “Why is this a problem? Cite the Firebase docs section.”
  3. Deploy to a preview channel, not production:
firebase hosting:channel:deploy preflight --expires 2d

This returns a temporary public URL and the channel auto-expires (7 days by default; --expires accepts values like 1h, 2d). Smoke-test exactly the routes the audit flagged. 6. Promote to production with firebase deploy --only hosting. Watch logs for 5 minutes for cold-start latency on any function the audit flagged for region drift.

How to make it repeatable

  • Save the audit prompt with your project name, build tool, and region baked in. One version per repo.
  • Keep a short “previously caught” note per project. Patterns repeat, and the model does not remember across sessions.
  • Re-run quarterly even with no code changes. Firebase deprecates flags and your config goes stale.
  • For teams, paste the audit findings into the PR description so the reviewer sees what changed and why, then point them at the preview-channel URL.

The full loop, config plus recent-changes summary plus region declaration, audit, diffs, apply, preview deploy, smoke test, promote, takes 10 to 15 minutes. A bad ship and rollback takes an hour and happens in front of users.

Common mistakes

  • Skipping the audit on “small” deploys. Small deploys are exactly when a rewrite typo slips through.
  • Pasting only firebase.json without the function entry file, so the AI cannot verify bindings.
  • Asking “is this OK?” instead of running the structured checklist. Open prompts produce vague answers.
  • Accepting prose fixes instead of diffs.
  • Pushing straight to production without a preview channel.
  • Leaving “nit” findings unfixed until they compound into next month’s outage.

FAQ

  • Does the AI know my Firebase project settings? No, only what you paste. Region, project ID, and recent changes must be stated explicitly.
  • Can it audit Firestore rules too? Yes. Paste firestore.rules and ask for a separate audit in the same structured-finding format.
  • What about App Check or billing config? Those are not in firebase.json. Include screenshots of the relevant console pages if you want them reviewed.
  • How is this different from firebase deploy --dry-run? Dry-run validates JSON syntax and that named functions resolve. The AI catches semantic errors: wrong order, wrong region, wrong cache target.
  • Which model should I use? Either flagship works. As of June 2026, Claude Opus 4.7 and GPT-5.5 both handle a few-hundred-line config easily; both read 1M-token context on their top tiers, so a large functions/ tree fits in one paste.
  • Can I automate this? Yes. Wire the prompt into a pre-deploy script that pipes firebase.json and git diff to the model and exits non-zero on any blocker.

Tags: #AI coding #Tutorial