Firebase

Firestore via the Firebase Admin SDK. This variant uses server-side service-account credentials, not the Firebase web SDK config snippet, and requires a small amount of first-run console setup before auth flows succeed.

Setup

  1. Go to console.firebase.google.com and create a project
  2. Navigate to Project Settings - Service accounts
  3. Click Generate new private key - this downloads a JSON file
  4. From the JSON file, copy: project_id, client_email, private_key
  5. Enable the Firestore API for the project if it is not already enabled
  6. Create the Firestore Database under Build - Firestore Database and use the default database
  7. Add the three env vars to .env.local

Environment variables

.env.local
FIREBASE_PROJECT_ID=my-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xxxxx@my-project-id.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIIEvQIBAD...
-----END PRIVATE KEY-----
"

Use Admin credentials

The Firebase variant is built around the Admin SDK. That means the app connects to Firestore with a service account and performs all auth-related reads and writes on the server.

lib/db/firebase.ts
import { initializeApp, getApps, cert } from 'firebase-admin/app'
import { getFirestore } from 'firebase-admin/firestore'

function getFirebaseAdmin() {
  if (getApps().length > 0) return getApps()[0]

  if (!process.env.FIREBASE_PROJECT_ID ||
      !process.env.FIREBASE_CLIENT_EMAIL ||
      !process.env.FIREBASE_PRIVATE_KEY) {
    throw new Error('Missing Firebase Admin environment variables')
  }

  return initializeApp({
    credential: cert({
      projectId: process.env.FIREBASE_PROJECT_ID,
      clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
      privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\n/g, '
'),
    }),
  })
}

export function getFirestore() {
  getFirebaseAdmin()
  return getFirestore()
}

Troubleshooting

Invalid PEM formatted message

FIREBASE_PRIVATE_KEY is malformed. Use the full private_key from the service-account JSON file, including BEGIN and END wrapper lines, and keep it quoted with escaped \n characters.

PERMISSION_DENIED for firestore.googleapis.com

The Firestore API is not enabled for the Google Cloud project behind your Firebase app. Enable it, then wait a few minutes for propagation before retrying.

NOT_FOUND on the first Firestore query

The default Firestore database does not exist yet, or the credentials point at a different project than the one you configured in the console. Create the default Firestore database and confirm the project ID matches your service account.

Composite index requirement

OTP verification and reset queries can require a composite index on the otps collection. If Firestore throws FAILED_PRECONDITION with a link, open that link and create the suggested index directly from the console.

  1. Trigger the failing verification or reset request.
  2. Open the index-creation URL included in the error.
  3. Create the proposed index for the otps collection.
  4. Wait until the index status becomes Enabled.
  5. Retry the auth flow.