NextAuth调用signIn后未在Firebase Authentication创建用户求助
解决NextAuth登录后未在Firebase Authentication中创建用户的问题
我当前在项目中使用NextAuth + Firebase,现有代码能正常处理认证和会话,但发现登录后不会在Firebase Authentication中创建用户,导致无法追踪Firebase原生的日活跃用户(DAU)等核心指标。虽然看过Firebase官方文档,但不知道怎么适配NextAuth的流程,求解决方案。
现有代码如下:
登录组件 LoginButton.tsx
import { useSession, signIn, signOut } from 'next-auth/react'; const ScraftIcon = () => { const { data: session } = useSession(); return ( <Tooltip title="Log In"> <button onClick={() => signIn('google')} > <MdLogin size="30" /> </button> </Tooltip> ); }; export default ScraftIcon;
NextAuth配置文件 [...nextauth].ts
import NextAuth from "next-auth"; import GoogleProvider from "next-auth/providers/google"; import { FirestoreAdapter } from "@next-auth/firebase-adapter"; import { cert } from "firebase-admin/app"; import "firebase/firestore"; export const authOptions = { providers: [ GoogleProvider({ clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID!, clientSecret: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET!, }), ], adapter: FirestoreAdapter({ credential: cert({ projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, clientEmail: process.env.NEXT_PUBLIC_FIREBASE_CLIENT_EMAIL, privateKey: process.env.NEXT_PUBLIC_FIREBASE_PRIVATE_KEY, }), }), }; export default NextAuth(authOptions);
问题根源
你使用的@next-auth/firebase-adapter仅负责将用户数据存储到Firestore数据库,不会自动同步到Firebase Authentication系统——这两个是Firebase生态中独立的模块,因此需要在NextAuth的登录回调中手动调用Firebase Admin SDK来创建/同步用户到Firebase Auth。
修复步骤
修改[...nextauth].ts配置
完善Firebase Admin初始化逻辑,并添加signIn回调实现用户同步:
import NextAuth from "next-auth"; import GoogleProvider from "next-auth/providers/google"; import { FirestoreAdapter } from "@next-auth/firebase-adapter"; import { cert, getApps, initializeApp } from "firebase-admin/app"; import { getAuth } from "firebase-admin/auth"; import "firebase/firestore"; // 初始化Firebase Admin(避免重复初始化) if (!getApps().length) { initializeApp({ credential: cert({ projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, clientEmail: process.env.NEXT_PUBLIC_FIREBASE_CLIENT_EMAIL, privateKey: process.env.NEXT_PUBLIC_FIREBASE_PRIVATE_KEY?.replace(/\\n/g, '\n'), }), }); } const adminAuth = getAuth(); export const authOptions = { providers: [ GoogleProvider({ clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID!, clientSecret: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET!, }), ], adapter: FirestoreAdapter({ credential: cert({ projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, clientEmail: process.env.NEXT_PUBLIC_FIREBASE_CLIENT_EMAIL, privateKey: process.env.NEXT_PUBLIC_FIREBASE_PRIVATE_KEY?.replace(/\\n/g, '\n'), }), }), // 添加SignIn回调同步用户到Firebase Auth callbacks: { async signIn({ user }) { try { // 检查Firebase Auth中是否已存在该用户 await adminAuth.getUserByEmail(user.email!); return true; // 用户已存在,允许登录 } catch (error) { // 用户不存在,创建新用户 if (error.code === 'auth/user-not-found') { await adminAuth.createUser({ email: user.email!, emailVerified: user.emailVerified, displayName: user.name, photoURL: user.image, uid: user.id, // 可选:用NextAuth的用户ID作为Firebase Auth的UID,保持数据一致性 }); return true; } // 其他错误,拒绝登录并打印日志 console.error('Firebase Auth同步失败:', error); return false; } }, }, }; export default NextAuth(authOptions);
关键细节说明
- 私钥处理:环境变量中的私钥可能会将换行符转义为
\\n,需要用replace(/\\n/g, '\n')还原,避免Firebase Admin初始化失败。 - UID一致性:创建Firebase Auth用户时指定
uid: user.id,可让Firebase Auth的用户ID与NextAuth存储在Firestore中的用户ID保持一致,方便后续数据关联。 - 错误边界:仅在捕获到
user-not-found错误时创建新用户,其他异常直接拒绝登录并打印日志,避免不可控问题。
验证效果
- 重新部署项目后用Google账号登录。
- 打开Firebase控制台 → Authentication → 用户,即可看到刚登录的用户已被创建。
- 等待一段时间后,Firebase Analytics模块就能正常统计DAU等原生指标。
内容的提问来源于stack exchange,提问作者Tyler Kim
相关产品推荐
相关产品推荐

