Next.js引入Firebase v9 Analytics报window is not defined错误如何解决
错误原因
Next.js 存在服务端渲染(SSR/SSG/ISR)执行阶段,该阶段运行在 Node.js 环境,不存在浏览器特有的 window 对象。而 Firebase 的 getAnalytics() 方法内部依赖 window 对象,直接全局初始化时会在服务端执行阶段抛出错误。
修复方案
步骤1:修改Firebase初始化代码,仅在浏览器环境初始化Analytics
调整原有初始化逻辑,加入浏览器环境判断,同时可以用Firebase内置的isSupported方法校验当前环境是否支持Analytics:
import { initializeApp, getApps, getApp } from "firebase/app"; import { getAnalytics, isSupported } from "firebase/analytics"; import { getAuth } from 'firebase/auth' import { getFirestore } from '@firebase/firestore' const firebaseConfig = { // 保留原有配置 }; // 初始化Firebase核心 const app = !getApps().length ? initializeApp(firebaseConfig) : getApp(); const auth = getAuth(); const db = getFirestore(app) // 仅浏览器环境初始化Analytics let analytics; if (typeof window !== 'undefined') { isSupported().then(isSupport => { if (isSupport) { analytics = getAnalytics(app); } }) } export {auth, db, analytics}
步骤2:调用Analytics时增加存在性判断
后续调用Analytics相关方法(如埋点上报)时,先判断analytics是否存在,避免服务端执行时报错:
import { logEvent } from "firebase/analytics"; import { analytics } from "@/lib/firebase"; // 替换为你自己的Firebase配置文件路径 // 埋点上报示例 if (analytics) { logEvent(analytics, "page_view", { page_path: window.location.pathname }); }
可选优化:封装通用埋点方法
避免每次调用都做判断,可以封装统一的埋点工具函数:
// 在firebase配置文件中新增导出 export const logAnalyticsEvent = async (eventName, eventParams = {}) => { if (typeof window === 'undefined') return; const supported = await isSupported(); if (!supported) return; if (!analytics) { analytics = getAnalytics(app); } logEvent(analytics, eventName, eventParams); }
后续直接调用logAnalyticsEvent("事件名", 参数)即可,无需额外判断。
内容的提问来源于stack exchange,提问作者maurice
相关产品推荐
相关产品推荐

