我一直在开发 firebase+next.js 应用程序,但我定义的唯一 API 端点无论如何都会返回空(即使我让它返回虚拟静态数据)。
这是我所做的: 在app文件夹内,创建了一个api文件夹,并在api内创建了users文件夹。 在用户内部,只有
route.js
。
// This is where you get the data from the API to the frontend.
import { firestore } from "@/firebase/server";
import { NextRequest, NextResponse } from "next/server";
// DummyData to test the API connection.
export type userOverview = {
firstName: String,
lastName: String,
}
const defaultUsersFirst: userOverview[] = [
{
"firstName": "John",
"lastName": "Doe",
}
]
export async function GET(request: NextRequest){
try{
if (!firestore){
return new NextResponse("Internal Error: no firestore", {status:500});
}
const response = await firestore.collection("users").get();
const users = response.docs.map((doc) => doc.data());
console.log(users)
console.log(defaultUsersFirst);
// no data in the emulator. add dummy data.
if(users.length <= 0){
const batch = firestore.batch();
defaultUsersFirst.forEach((user) => {
const userRef = firestore?.collection("users").doc();
if(userRef) batch.set(userRef, user);
})
batch.commit();
return NextResponse.json(defaultUsersFirst);
}
return NextResponse.json(users);
} catch (error){
return new NextResponse("Internal Error", {status: 500});
}
}
然后,在应用程序内部还有一个用于端点的用户文件夹,其中只有一个
page.tsx
。
那个看起来像这样:
import { userOverview } from "../api/users/route";
import Table from "@/components/table";
export default async function Users() {
let users: userOverview[] = [];
const response = await fetch(`${process.env.API_URL}/api/users`);
if (response.ok) {
// debug
console.log("getting response json")
const usersJson = await response.json();
users = usersJson;
console.log(usersJson)
} else {
console.error('Failed to fetch users:', response.statusText);
}
return (
<div className="flex flex-col items-center mt-8">
{users.toString()}
</div>
);
}
现在使用我在这里写的这些日志,我可以看到从用户 api 获取的任何内容始终是空的。
关于我的设置,我可以从我的网络连接到本地模拟器,并且我在设置时安装了必要的依赖项
firebase init
。而且,我也这么做了npm install firebase firebase-admin
,也是为了安全起见。
为了正确分类代码,在根项目目录中,我创建了一个 firebase 文件夹,其中有一个名为
serviceAccount.json
的文件,这是由 firebase 项目生成的 admin sdk 的密钥。
设置 firebase 时获得的函数文件夹也在该文件夹内。 最后,这个文件夹里面有
server.ts
:
import serviceAccount from "./serviceAccount.json";
import { initializeApp, ServiceAccount, cert, getApps } from "firebase-admin/app";
import { Firestore, getFirestore } from "firebase-admin/firestore";
let firestore : Firestore | undefined = undefined;
const currentApps = getApps();
if (currentApps.length <= 0) {
if (process.env.NEXT_PUBLIC_APP_ENV === "emulator") {
process.env["FIRESTORE_EMULATOR_HOST"] =
process.env.NEXT_PUBLIC_EMULATOR_FIRESTORE_PATH;
process.env["FIREBASE_AUTH_EMULATOR_HOST"] =
process.env.NEXT_PUBLIC_EMULATOR_AUTH_PATH;
}
const app = initializeApp({
credential: cert(serviceAccount as ServiceAccount),
});
firestore = getFirestore(app);
console.log("firestore working");
} else {
firestore = getFirestore(currentApps[0]);
console.log("firestore working");
}
export { firestore };
我的 .env.development 可能需要一些额外信息,如下所示:
API_URL=http://localhost:3000
NEXT_PUBLIC_EMULATOR_FIRESTORE_PATH=127.0.0.1:8080
NEXT_PUBLIC_EMULATOR_AUTH_PATH=127.0.0.1:9099
我已经调整了我的 package.json 以将工作环境设置为开发,以便我可以使用模拟器而不是实际的 firestore。
package.json:
...
"scripts": {
"dev": "NEXT_PUBLIC_APP_ENV='emulator' next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"emulators": "firebase emulators:start"
},
...
为了提供有关项目结构的一些想法,我添加了根目录中的文件夹结构作为图像。
感谢您的宝贵时间。
如上所示,我尝试以某种方式设置 api 端点,如果 firestore 集合为空,则向其中添加虚拟数据并返回它。然而,现在它总是返回空。
您是否已在本地模拟器中插入用户集合?为了让它发挥作用,我相信你需要有它。