Next.js 12中Firestore的await setDoc无响应:服务端/客户端代码问题?
问题分析与解决方案
你的问题核心是Firebase在Next.js SSR环境下的初始化逻辑错误,导致客户端使用了服务端创建的Firestore实例,进而调用setDoc时无响应。
问题根源
在initFirebase.js中,你在全局作用域直接执行了initializeApp(clientCredentials),这会在Next.js的服务端渲染阶段运行,创建了服务端的Firebase App实例。而导出的db变量是基于这个服务端实例生成的,客户端组件直接使用这个db时,无法正常和Firestore服务通信。
同时你在Home组件中调用的initFirebase函数,仅在客户端初始化Firebase,但此时导出的db已经是服务端实例,客户端的初始化没有被用到。
修正步骤
1. 重构initFirebase.js
修改初始化逻辑,确保只在客户端初始化Firebase,并且db实例始终基于客户端的App创建:
import { initializeApp } from "firebase/app"; import { getFirestore } from "firebase/firestore"; const clientCredentials = { apiKey: process.env.PUBLIC_FIREBASE_API_KEY, authDomain: process.env.PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.PUBLIC_FIREBASE_PROJECT_ID, }; let app; let db; if (typeof window !== "undefined") { // 仅在客户端初始化Firebase app = initializeApp(clientCredentials); db = getFirestore(app); console.log("Firebase客户端初始化成功"); } export { db };
2. 移除Home组件中的initFirebase调用
现在初始化逻辑已经自动在客户端执行,不需要手动调用initFirebase:
import { Inter } from 'next/font/google' import WriteToCloudFirestore from "@/componenets/cloudFirestore/Write"; const inter = Inter({ subsets: ['latin'] }) export default function Home() { return (...) }
3. 保留Write.js的逻辑不变
你的sendData函数逻辑是正确的,修正初始化后,点击按钮就能正常写入Firestore。
验证逻辑
修正后,db变量仅在客户端环境下被赋值,确保客户端组件使用的是正确的Firestore实例,调用setDoc时就能正常触发网络请求并写入数据。
内容的提问来源于stack exchange,提问作者The_FORUM
相关产品推荐
相关产品推荐

