5. Firebase as Sole Infrastructure Vendor
Status
Superseded — 2026-04-24
Superseded by ADR 0018. Originally accepted 2026-02-14 (project inception).
Context
jjk.engineer is a solo-maintained blog with an admin surface, contact form, post ratings, timeclock, and a LinkedIn autoposter. It needs hosting, serverless compute, a database, auth, abuse prevention, feature flags, and secret storage. The realistic alternatives are either a multi-vendor stack (Vercel/Netlify + Supabase/Neon + Cloudflare + a secrets manager) or a single consolidated platform. Multi-vendor buys best-of-breed and portability; consolidation buys one auth model, one dashboard, one billing surface, and one mental model.
Decision
Firebase is the sole infrastructure vendor. Everything the site depends on at runtime runs on Google Cloud via Firebase services.
- Hosting — static + prerendered assets for
blogandsludge-reporttargets - Cloud Functions — all backend mutations and triggers
- Firestore — sole datastore for dynamic data
- Auth — single-admin account with custom claims for role
- App Check — reCAPTCHA Enterprise, required on all callable functions
- Remote Config — feature flags and tunables (e.g., admin idle timeout)
- Secret Manager — Resend, LinkedIn, and other API keys, accessed via
defineSecret() - Storage — assets not shipped with the bundle
- Performance Monitoring — wrapped by an internal
PerformanceService
Third-party services (Resend for email, Sentry for error reporting, LinkedIn API, Gemini API) are called from Cloud Functions, not from the client.
Consequences
- One identity model (Firebase Auth) propagates through every layer: Firestore rules, callable function auth context, App Check tokens, Admin SDK writes. Cross-service auth plumbing disappears.
- Local development uses the Firebase emulator suite as a single unit. There is no per-service docker-compose to maintain.
- Billing and observability concentrate in one GCP project. Cost surprises come from one source and are attributable.
- Vendor lock-in is real and accepted. Firestore’s data model, the callable-function invocation shape, App Check’s enforcement hook, and Remote Config’s client API are all Firebase-specific. Migrating off would be a rewrite of the data and auth layers, not a config swap.
- Feature choices are constrained to what Firebase offers. Adopting Postgres, a different auth provider, or a different edge platform means exiting this decision.
- Third-party integrations live behind the function boundary. Swapping Resend for another transactional email provider is a function-local change; the rest of the system does not know.
- The GCP resource layer beneath Firebase (APIs, service accounts, IAM, secrets, database/bucket config) is managed by Terraform as an infrastructure-as-code substrate. This does not replace Firebase — it codifies the prerequisites that must exist before
firebase deploysucceeds. See ADR 0012 — Terraform for GCP Resource Management.