You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

next-auth对接Firebase遇问题:开启安全规则后无法读写数据

问题描述

我在Next.js应用中配置了NextAuth的Google登录提供商,已设置Web客户端ID与密钥,但使用Google登录后,Firebase控制台未创建用户,也无法识别已登录用户。关闭Firebase安全规则时可正常读写Firestore文档,但设置allow read, write: if request.auth != null;规则后则无法操作。曾尝试使用FirestoreAdapter但未成功,想了解是遗漏了配置还是该方案暂不适合生产环境?


现有配置代码

[...nextauth].js

import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import { firebaseConfig } from "../../../src/lib/firebase";
// import { FirestoreAdapter } from "@next-auth/firebase-adapter";

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_WEB_CLIENT_ID,
      clientSecret: process.env.GOOGLE_WEB_CLIENT_SECRET,
    }),
  ],
  pages: {
    signIn: "/auth/sign-in",
  },
  // 目前暂未启用适配器
  // adapter: FirestoreAdapter({
  // apiKey: "",
  // authDomain: "",
  // projectId: "",
  // storageBucket: "",
  // messagingSenderId: "",
  // appId: "",
  // measurementId: "",
  // Optional emulator config (see below for options)
  // emulator: {},
  // }),
  // ...
});

登录组件代码

{Object.values(providers).map((provider) => (
                <div key={provider.name}>
                  <button
                    className={styles.signInButton}
                    onClick={() => signIn(provider.id, { callbackUrl: "/" })}
                  >
                    用{provider.name}登录
                  </button>
                </div>
              ))}

Firestore文档创建测试代码

const docRef = await addDoc(collection(db, "tests"), {
      fullName: values.fullName,
      createdAt: serverTimestamp(),
    });

核心原因与解决办法

1. 根本问题:两个独立的身份系统

NextAuth的登录状态和Firebase Auth完全不互通——你用NextAuth完成Google登录后,Firebase完全不知道用户已登录,所以request.auth始终为null,触发安全规则拦截。而FirestoreAdapter只是用来存储NextAuth的用户数据到Firestore,不会同步到Firebase Auth用户池,也无法让Firebase识别NextAuth的登录状态。

2. 可行解决方向

方案一:登录后同步到Firebase Auth

在NextAuth登录成功后,用Google返回的ID Token去Firebase Auth创建/关联用户,让两边身份同步:

import { getAuth, signInWithCredential, GoogleAuthProvider } from "firebase/auth";
import { app } from "../../../src/lib/firebase";

export default NextAuth({
  // ... 原有配置
  callbacks: {
    async jwt({ token, account }) {
      // 首次登录时获取Google的id_token并同步到Firebase Auth
      if (account?.provider === "google" && account.id_token) {
        const auth = getAuth(app);
        const credential = GoogleAuthProvider.credential(account.id_token);
        const userCredential = await signInWithCredential(auth, credential);
        // 把Firebase用户ID存入token备用
        token.firebaseUid = userCredential.user.uid;
      }
      return token;
    },
    async session({ session, token }) {
      // 将Firebase UID同步到前端session
      session.user.firebaseUid = token.firebaseUid;
      return session;
    }
  },
});

方案二:直接用Firebase Auth处理登录

如果核心依赖Firebase生态,放弃NextAuth的Google提供商,直接用Firebase Auth的登录能力更省心:

  • 前端调用signInWithPopup(auth, new GoogleAuthProvider())完成登录
  • 自动同步到Firebase Auth用户池,Firestore的request.auth会正常识别
  • 若需NextAuth的session管理,可将Firebase Auth的token传入NextAuth做二次封装

方案三:自定义Firestore安全规则适配NextAuth(不推荐生产)

若坚持用NextAuth身份,需在请求Firestore时携带NextAuth的session token,通过Cloud Functions编写验证函数,在安全规则中调用验证。但这种方式复杂度高,安全性不如官方Auth系统,不建议生产环境使用。

3. FirestoreAdapter的正确定位

FirestoreAdapter只是NextAuth的数据存储适配器——它把NextAuth的用户、会话等数据存在你的Firestore中,方便管理NextAuth的用户数据,但和Firebase Auth没有关联,无法解决request.auth的鉴权问题。


内容的提问来源于stack exchange,提问作者BenjaminK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:17:01