Firebase integration

Integrate Firebase into your Aurelia 2 application for authentication, Cloud Firestore, and cloud storage using the current modular Firebase JavaScript SDK. This recipe shows a minimal-yet-production-ready setup that honors Aurelia's dependency injection patterns and Firebase's best practices.

Prerequisites

  • Aurelia 2 workspace (the Vite + TypeScript starter works great)

  • Node and npm versions that match the Aurelia workspace template (use npm run env in the root if you need to confirm)

  • Firebase project with the following enabled in the console:

    • Web App registration (App ID + config object)

    • Authentication → Email/Password provider

    • Cloud Firestore (in Production mode) and a ruleset drafted for your app

  • Optional but recommended: Firebase Emulator Suite configured locally

Install the Firebase SDK

Install the modular SDK and (optionally) the CLI for emulators/deploys:

npm install firebase
npm install -D firebase-tools

Configure environment secrets

Firebase config values should never be hard-coded. With the Vite-powered Aurelia starter, define them in .env.local (never commit this file):

Then expose a typed config object:

Central Firebase service (DI-friendly)

Create a singleton service that initializes Firebase exactly once, exposes Auth + Firestore, and opts into IndexedDB persistence for offline support.

Register the service

Email/password authentication component

Firestore-backed todo list

Sync Firebase with @aurelia/state

Use @aurelia/state when you want Firebase-authenticated users and Firestore documents to feed a single app-wide state tree that templates can bind to with .state and .dispatch.

Define the global state

Register the store next to Firebase

Bind templates directly to the store

Because the state lives in a central store, any component can consume it without managing its own Firestore subscription:

Use .state or & state wherever you would normally bind to local view-model fields. All Firebase updates flow through the store exactly once, which keeps components simple and makes it trivial to add middleware (analytics, logging, optimistic updates, etc.).

Firestore security rules (minimal example)

Tighten the predicate to match your data model (e.g., ensure a ownerId matches request.auth.uid). Always test rule changes in the Emulator Suite before deploying.

Local development & testing

  1. Authenticate the CLI once: npx firebase login.

  2. Configure emulators: npx firebase init emulators --only firestore,auth.

  3. Start them alongside Aurelia:

  4. Point the SDKs to emulators during development (set VITE_USE_FIREBASE_EMULATORS=true in .env.local so the service snippet can detect it):

Additional best practices

  • Use serverTimestamp() (as shown) so writes rely on Google time instead of client clocks.

  • Prefer query + orderBy with indexes over client-side filtering to avoid hot documents.

  • Clean up listeners (unsubscribe) whenever components detach to prevent memory leaks.

  • Keep Firebase config in environment files and rotate API keys if compromised.

  • Run npm run build and npm run test with the Emulator Suite before deploying new rules.

This integration pattern keeps Firebase initialization isolated, leans on Aurelia's DI system, and follows modern Firebase recommendations for security, offline resilience, and testing.

Last updated

Was this helpful?