AgentStack
SKILL verified MIT Self-run

Firestore Better Auth

skill-yultyyev-better-auth-firestore-firestore-better-auth · by yultyyev

>-

No reviews yet
0 installs
2 views
0.0% view→install

Install

$ agentstack add skill-yultyyev-better-auth-firestore-firestore-better-auth

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Firestore Better Auth? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Firestore Adapter for Better Auth

better-auth-firestore is the Firestore database adapter for Better Auth. It stores users, sessions, accounts, and verification tokens in Firestore using the Firebase Admin SDK.

Package: better-auth-firestoreGitHub · npm


Install

pnpm add better-auth-firestore firebase-admin better-auth

Minimal setup

import { firestoreAdapter } from "better-auth-firestore";
import { betterAuth } from "better-auth";
import { getFirestore } from "firebase-admin/firestore";

export const auth = betterAuth({
  database: firestoreAdapter({ firestore: getFirestore() }),
});

Full setup with credentials

import { betterAuth } from "better-auth";
import { firestoreAdapter, initFirestore } from "better-auth-firestore";
import { cert } from "firebase-admin/app";

const firestore = initFirestore({
  credential: cert({
    projectId: process.env.FIREBASE_PROJECT_ID!,
    clientEmail: process.env.FIREBASE_CLIENT_EMAIL!,
    privateKey: process.env.FIREBASE_PRIVATE_KEY!.replace(/\\n/g, "\n"),
  }),
  projectId: process.env.FIREBASE_PROJECT_ID!,
  name: "better-auth",
});

export const auth = betterAuth({
  database: firestoreAdapter({
    firestore,
    namingStrategy: "default", // or "snake_case"
    collections: {
      // users: "users",
      // sessions: "sessions",
      // accounts: "accounts",
      // verificationTokens: "verificationTokens",
    },
  }),
});

Options

| Option | Type | Default | Description | |---|---|---|---| | firestore | Firestore | getFirestore() | Firebase Admin Firestore instance | | namingStrategy | "default" \| "snake_case" | "default" | Collection naming convention | | collections | object | see below | Override individual collection names | | debugLogs | boolean | false | Enable verbose query logging |

Default collection names:

  • users"users"
  • sessions"sessions"
  • accounts"accounts"
  • verificationTokens"verificationTokens" (default) or "verification_tokens" (snake_case)

Required Firestore composite index

The adapter requires a composite index on the verification collection for token lookups. Without it, Better Auth sign-in verification will fail.

Quick setup — generate the Firebase Console URL:

import { generateIndexSetupUrl } from "better-auth-firestore";
const url = generateIndexSetupUrl(process.env.FIREBASE_PROJECT_ID!);
console.log(url); // Open to auto-fill the index form

Or deploy via CLI:

Copy firestore.indexes.json from node_modules/better-auth-firestore/ to your project root, then:

firebase deploy --only firestore:indexes

Index fields:

  • Collection: verification
  • identifier (Ascending)
  • createdAt (Descending)
  • __name__ (Descending)
  • Query scope: Collection

Environment variables

FIREBASE_PROJECT_ID=your-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk@your-project.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"

Important: FIREBASE_PRIVATE_KEY often arrives with literal \n strings in env vars. Always replace them:

privateKey: process.env.FIREBASE_PRIVATE_KEY!.replace(/\\n/g, "\n")

Migration from Auth.js / NextAuth Firebase adapter

better-auth-firestore uses the same collection names and field shapes as the Auth.js Firebase adapter by default — it is a drop-in replacement.

// Before (Auth.js)
import { FirestoreAdapter } from "@auth/firebase-adapter";

// After (Better Auth)
import { firestoreAdapter } from "better-auth-firestore";

export const auth = betterAuth({
  database: firestoreAdapter({ firestore }),
});

No Firestore data migration needed. Same users, sessions, accounts, and verificationTokens collections.


Using with the Firebase Auth plugin

To also use Firebase Authentication (Phone OTP, Google Sign-In, Email/Password), combine with better-auth-firebase-auth:

import { firestoreAdapter } from "better-auth-firestore";
import { firebaseAuthPlugin } from "better-auth-firebase-auth/server";

export const auth = betterAuth({
  database: firestoreAdapter({ firestore }),
  plugins: [firebaseAuthPlugin({ firebaseAdminAuth: getAuth() })],
});

Firestore Emulator (local development & tests)

# Start emulator
docker run -d --rm -p 8080:8080 google/cloud-sdk:emulators \
  gcloud beta emulators firestore start --host-port=0.0.0.0:8080

# Set env and start dev server
FIRESTORE_EMULATOR_HOST=localhost:8080 pnpm dev

# Run tests
FIRESTORE_EMULATOR_HOST=localhost:8080 pnpm vitest run

No credentials or service account needed when using the emulator.


Runtime support

| Runtime | Supported | |---|---| | Node 18+ | ✅ | | Next.js on Vercel (Node.js runtime) | ✅ Recommended | | Cloud Functions / Cloud Run | ✅ | | Vercel Edge Runtime (runtime = 'edge') | ❌ Admin SDK requires Node.js | | Cloudflare Workers | ❌ Admin SDK requires Node.js |

Note: Vercel deploys work fine — the restriction is only when you explicitly opt into the Edge Runtime (export const runtime = 'edge'). The default Node.js serverless runtime on Vercel is fully supported.


Common mistakes

  • Missing Firestore composite index — Verification token queries fail with "index required" or "insufficient permissions". Run generateIndexSetupUrl to get the setup link.
  • FIREBASEPRIVATEKEY with literal \n — Always call .replace(/\\n/g, "\n") on the key before passing to cert().
  • Using at edge runtime — Firebase Admin SDK does not run on Vercel Edge or Cloudflare Workers. Use Node.js runtimes only.
  • Deprecated scoped package — Use better-auth-firestore (unscoped). The @yultyyev/better-auth-firestore package is deprecated.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.