Firestore/Firebase无法与Next.js配合使用

mxg2im7a  于 2023-01-14  发布在  其他
关注(0)|答案(4)|浏览(118)

嘿,你们真的在这里挣扎。
我尝试在我的Next.js应用程序中使用firebase,特别是针对API。当我在本地构建产品和本地开发时,它工作正常。但是一旦我在vercel平台上部署到产品中,我就得到了500 - Internal Server Error。我已经能够将错误缩小到由使用await getDocs(q)引起的,但不确定如何修复它。
本质上,我试图用firestore的数据进行动态API路由。
firebase.js

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getStorage } from "firebase/storage";

// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
  apiKey: "<REDACTED_FOR_STACKOVERFLOW>",
  authDomain: "<REDACTED_FOR_STACKOVERFLOW>",
  databaseURL: "<REDACTED_FOR_STACKOVERFLOW>",
  projectId: "<REDACTED_FOR_STACKOVERFLOW>",
  storageBucket: "<REDACTED_FOR_STACKOVERFLOW>",
  messagingSenderId: "<REDACTED_FOR_STACKOVERFLOW>",
  appId: "<REDACTED_FOR_STACKOVERFLOW>",
  measurementId: "<REDACTED_FOR_STACKOVERFLOW>"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Database
const db = getFirestore();
// Storage
const storage = getStorage(app)

export {
  app,
  storage,
  db
}

/api/users/[name].js

import { db } from './firebase.js'

export default async function handler(req, res) {
  try {
    const { name } = req.query
    let users = []
    const q = query(collection(db, "users"), where("name", "==", name))
    const querySnapshot = await getDocs(q)
    if (querySnapshot.empty) {
      res.status(404).json({error: "Document does not exist."})
    } else {
      querySnapshot.forEach((doc) => {
        users.push(doc.data())
      })
      res.status(200).json(users)
    }
  } catch(err) {
    res.status(404).json({error: err})
  }
}

package.json

{
  "name": "app-frontend",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@headlessui/react": "^1.4.2",
    "@heroicons/react": "^1.0.5",
    "bootstrap": "^4.6.0",
    "classnames": "^2.2.6",
    "next": "11.0.1",
    "firebase": "^9.5.0",
    "postcss-custom-properties": "^8.0.11",
    "postcss-flexbugs-fixes": "^5.0.2",
    "postcss-import": "^14.0.2",
    "postcss-nested": "^5.0.5",
    "postcss-nesting": "^8.0.1",
    "postcss-preset-env": "^6.7.0",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-icons": "^4.2.0",
    "react-markdown": "^6.0.2",
    "react-pro-sidebar": "^0.6.0",
    "react-remark": "^2.0.3",
    "rehype-raw": "^5.1.0",
    "rehype-react": "^6.2.1",
    "remark-html": "^13.0.1",
    "remark-react": "^8.0.0",
    "remark-rehype": "^8.1.0",
    "sass": "^1.35.1",
    "xhr2": "^0.2.1"
  },
  "devDependencies": {
    "autoprefixer": "^10.2.6",
    "eslint": "7.29.0",
    "eslint-config-next": "11.0.1",
    "postcss": "^8.3.5",
    "tailwindcss": "^2.2.4"
  }
}

服务器端的错误如下所示:@firebase/firestore: Firestore (9.5.0): INTERNAL UNHANDLED ERROR: Error: ENOENT: no such file or directory, open '/var/task/node_modules/@firebase/firestore/dist/src/protos/google/firestore/v1/firestore.proto'

blmhpbnm

blmhpbnm1#

问题是依赖项不知何故安装在本地包node_modules中,但没有在package.json中定义。
您需要在package.json上定义它,以便在构建阶段安装它
在项目文件夹上,打开终端并安装它,这样它将被添加到包中:

npm install --save firebase
alen0pnh

alen0pnh2#

为此,如果您在getServerSideProps中使用handler函数或在index.js中使用其他函数,请尝试使用以下代码:

const q = query(collection(getFirestore(app), "users"), where("name", "==", name))

这对我很有效谢谢

vngu2lb8

vngu2lb83#

把firebase降级到9.4.0对我来说解决了这个问题。我不确定这是否是一个好的修复,但是它确实有效。

5f0d552i

5f0d552i4#

我有一段时间也遇到过同样的问题,问题是您正在客户端中使用初始化App的方法。
对于基于节点或服务器的初始化,执行以下操作:

  • 进入firebase控制台,在Project Settings〉service account中导出一个新的密钥(导出一个json文件,应该位于项目的根目录下)
  • 然后创建utils/db.js,并在内部导入json文件并初始化应用程序:
import serviceAccount from "./file.json";

if (!admin.apps.length) {
  try {
    admin.initializeApp({
      credential: admin.credential.cert(serviceAccount),
    });
  } catch (error) {
    console.log("Firebase admin initialization error", error.stack);
  }
}
export default admin.firestore();

如果你同时使用SSR和CSR,请保持客户端和服务器端的firebase连接。
然后在您的页面/api/whetever. js中

import db from "/utils/db.js";

export default async function handler(req, res) {
  try {
    const entries = await db.collection("collection").get();
    const entriesData = entries.docs.map((entry) => ({
      id: entry.id,
      ...entry.data(),
    }));
    res.status(200).json({ entriesData });
  } catch (e) {
    res.status(400).end();
  }
}

通过调用本地主机:3000/API/whatever进行测试

相关问题