Does Firebase Work With Auth.js?
Firebase and Auth.js can work together, but you're duplicating authentication logic—Auth.js doesn't natively support Firebase Auth providers without custom integration.
Quick Facts
How Firebase Works With Auth.js
Firebase Authentication and Auth.js solve similar problems but operate differently. Auth.js is session-based middleware designed for Next.js and other frameworks, while Firebase Auth is a client-side SDK with its own session management. The typical pattern is using Firebase Auth directly in your client code and leveraging Auth.js only for server-side session wrapping—this creates maintenance overhead since you're managing two auth systems. A better approach: use Auth.js with custom Firebase credentials provider, storing Firebase ID tokens in Auth.js sessions. This centralizes auth logic but requires custom JWT handling and token refresh logic. Alternatively, skip Auth.js entirely and use Firebase Auth directly with middleware—simpler but less framework integration. The gotcha is that Firebase's real-time features and Firestore security rules work best with Firebase Auth tokens, not Auth.js sessions, so you'll need to bridge them carefully. Most developers find this combo useful only if they're heavily invested in Auth.js ecosystem and want Firebase's database features separately.
Best Use Cases
Firebase Auth with Auth.js Session Bridge
npm install next-auth firebase firebase-admin// lib/auth.ts - Auth.js configuration
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import NextAuth from 'next-auth';
import Credentials from 'next-auth/providers/credentials';
import { initializeApp as initializeAdminApp } from 'firebase-admin/app';
import { getAuth as getAdminAuth } from 'firebase-admin/auth';
const firebaseConfig = { /* your config */ };
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const { handlers, signIn, signOut, auth: authSession } = NextAuth({
providers: [
Credentials({
async authorize(credentials: any) {
try {
const decodedToken = await getAdminAuth().verifyIdToken(
credentials.idToken
);
return { id: decodedToken.uid, email: decodedToken.email };
} catch (error) {
return null;
}
},
}),
],
});
// pages/api/auth/signin.ts - Receive Firebase token, create session
import { signIn } from '@/lib/auth';
export default async function handler(req: any, res: any) {
const { idToken } = req.body;
await signIn('credentials', { idToken, redirect: false });
res.status(200).json({ ok: true });
}Known Issues & Gotchas
Firebase ID tokens expire every hour; Auth.js sessions have separate expiration
Fix: Implement token refresh logic in Auth.js callbacks or use Firebase's onAuthStateChanged to refresh before expiry
Firestore security rules validate Firebase Auth tokens, not Auth.js sessions
Fix: Either pass Firebase ID token in client requests to Firestore, or disable security rules and rely on Auth.js middleware
No official Auth.js provider for Firebase Auth exists
Fix: Build a custom credentials provider using Firebase Admin SDK, or use Firebase Auth client-side only
Firebase's email/password auth doesn't integrate cleanly with Auth.js providers pattern
Fix: Use Firebase Auth client-side for login, then issue Auth.js session in callback route
Alternatives
- •Firebase Auth + custom middleware (skip Auth.js entirely for simpler auth flow)
- •Auth.js with Supabase (native PostgREST auth with similar DX, no duplicate systems)
- •Firebase Auth + Iron Session (lightweight session management without Auth.js overhead)
Resources
Related Compatibility Guides
Explore more compatibility guides