【问题标题】:Next-auth Google Auth & Firebase AdapterNext-auth Google 身份验证和 Firebase 适配器
【发布时间】:2021-12-20 21:28:36
【问题描述】:

当我尝试使用时

 adapter: FirebaseAdapter(firestore)

来自 -> https://next-auth.js.org/adapters/firebase

在 firebase v9 之后,next-auth 的文档没有更新。

我收到此错误:TypeError: collection is not a function

我的代码:

API 密钥和客户端密码已被替换为点 (...) 以隐藏它们。

    import NextAuth from "next-auth";
    import Providers from "next-auth/providers";
    import { FirebaseAdapter } from "@next-auth/firebase-adapter";
    import { getFirestore } from "firebase/firestore";
    import { initializeApp, getApps } from "firebase/app";
    import "firebase/firestore";
    
    const firebaseConfig = {
      apiKey: "...",
      authDomain: "...",
      projectId: "...",
      storageBucket: "...",
      messagingSenderId: "...",
      appId: "...",
      measurementId: "....",
    };
    
    const app = initializeApp(firebaseConfig);
    
    
    const firestore = getFirestore(app);
    
    
    const options = {
      providers: [
        Providers.Google({
          clientId:
            "...",
          clientSecret: "...",
         
        }),
      ],
    
      adapter: FirebaseAdapter(firestore),
    
      // database: process.env.MONGODB_URI,
    };
    
    export default (req, res) => {
      NextAuth(req, res, options);
    };

【问题讨论】:

  • 你在哪里调用这个文件?记住,Next 是同构的,所以你必须非常精确地知道你在哪里进行这样的后端调用。我通常将这样的内容加载到/lib 文件夹中。
  • 它在 [...nextauth].js 文件中。
  • 我在 Next 中遇到了环境变量可见性问题几次。我会将一些 console.log() 加入其中,看看它们是否通过,或者使用 VSCode 或类似中的断点逐步完成您的构建。

标签: firebase google-cloud-firestore next.js next-auth


【解决方案1】:

我设法使用以下方法解决了同样的错误:

1- 由于 firebase v9 遵循模块化方法,将解构的 FirebaseClient 对象传递给 firebase 适配器,如下所示

// pages/api/auth/[...nextauth].js
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import GithubProvider from "next-auth/providers/github";
import { FirebaseAdapter } from "@next-auth/firebase-adapter";
import { db } from "../../../firebase";

import {
  collection,
  query,
  getDocs,
  where,
  limit,
  doc,
  getDoc,
  addDoc,
  updateDoc,
  deleteDoc,
  runTransaction,
} from "firebase/firestore";

export default NextAuth({
  providers: [
    // OAuth authentication providers
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
    GithubProvider({
      clientId: "",
      clientSecret: "",
    }),
  ],

  adapter: FirebaseAdapter({
    db,
    collection,
    query,
    getDocs,
    where,
    limit,
    doc,
    getDoc,
    addDoc,
    updateDoc,
    deleteDoc,
    runTransaction,
  }),
});

2-然后您可能会收到一条错误消息,指出“无法使用未定义的 toDate 方法”,如果发生这种情况,请点击 index.js 文件中的 node_modules/@next-auth/firebase-adapter/dist 替换 exports.format 对象使用此代码添加“?”值对象后的运算符

exports.format = {
    toFirestore(object) {
        const newObjectobject = {};
        for (const key in object) {
            const value = object[key];
            if (value === undefined)
                continue;
            newObjectobject[key] = value;
        }
        return newObjectobject;
    },
    fromFirestore(snapshot) {
        if (!snapshot.exists())
            return null;
        const newUser = { ...snapshot.data(), id: snapshot.id };
        for (const key in newUser) {
            const value = newUser[key];
            if (value?.toDate)
                newUser[key] = value.toDate();
            else
                newUser[key] = value;
        }
        return newUser;
    },
};

3- 你要做的最后一件事是在 package.json 中删除下一个授权版本之前的“^”,以在你执行 npm install 时禁用包更新,这将重置步骤 2 中发生的所有代码更改。

此解决方案假设您有 firebase.js 文件,该文件应如下所示

import { initializeApp, getApps, getApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
import { getStorage } from "firebase/storage";

const firebaseConfig = {
  apiKey: "your_api_key",
  authDomain: "your_auth_domain",
  projectId: "your_project_Id",
  storageBucket: "your_storage_bucket",
  messagingSenderId: "message_sender_Id",
  appId: "your_app_Id",
};

// Initialize Firebase
const app = getApps.length > 0 ? getApp() : initializeApp(firebaseConfig);

const db = getFirestore(app);
const storage = getStorage(app);

export { app, db, storage };

希望这能解决您的问题。

【讨论】:

  • 我想到了另一种也可以工作的解决方案,但我还没有尝试过将 firebase 包恢复到 v8。
猜你喜欢
  • 2021-11-23
  • 2022-10-13
  • 1970-01-01
  • 2019-05-20
  • 2021-11-07
  • 2020-01-23
  • 2015-05-10
  • 1970-01-01
  • 2016-09-26
相关资源
最近更新 更多