Install
$ agentstack add skill-yultyyev-better-auth-firestore-firestore-better-auth ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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.
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-firestore — GitHub · 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
generateIndexSetupUrlto get the setup link. - FIREBASEPRIVATEKEY with literal
\n— Always call.replace(/\\n/g, "\n")on the key before passing tocert(). - 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-firestorepackage is deprecated.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: yultyyev
- Source: yultyyev/better-auth-firestore
- License: MIT
- Homepage: https://npmjs.com/package/better-auth-firestore
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.