Next.js生产环境Firebase emptyChildrenSingleton未定义报错
问题根因
该错误仅在生产环境触发的核心原因是:Next.js v12默认启用的SWC生产压缩器,和v9.8.x~v9.9.0版本区间的Firebase JS SDK存在兼容性问题,压缩过程中错误处理了@firebase/database包内部的emptyChildrenSingleton变量,导致运行时抛出未定义错误;开发环境不会执行代码压缩,因此逻辑运行正常。
另外你的Firebase初始化代码存在笔误,会偶发重复创建Firebase实例,提升异常触发概率:
// 错误逻辑:第二个判断读取的是getApps函数本身的length属性,而非已初始化应用列表的长度 if (getApps().length && getApps.length > 0) return getApps()[0];
修复方案
选择以下任意一种方案即可解决问题,优先选方案1:
- 方案1(推荐,改动最小):升级Firebase JS SDK到v9.9.1及以上版本,官方已修复该压缩兼容问题,执行以下命令升级:
npm install firebase@^9.9.1
- 方案2:如果暂时无法升级Firebase依赖,修改Next.js配置文件,关闭SWC压缩回退到Terser压缩,规避变量被错误处理的问题,配置示例:
/** @type {import('next').NextConfig} */ const nextConfig = { swcMinify: false, // 保留原有其他配置 } module.exports = nextConfig
- 方案3:修复初始化逻辑笔误,同时显式给数据库实例传入已初始化的Firebase App,避免时序问题,修正后的代码如下:
初始化逻辑:
import { getApps, initializeApp } from 'firebase/app'; const firebaseConfig = { // 填写你的Firebase配置项 }; const initFirebase = () => { const existingApp = getApps()[0]; if (existingApp) return existingApp; return initializeApp(firebaseConfig); }; export default initFirebase;
数据读取逻辑:
const [textData, setTextData] = useState<any[]>([]); useEffect(() => { fetchData(); }, []); const fetchData = () => { const app = initFirebase(); // 显式传入已初始化的app实例,避免隐式获取默认实例的时序问题 const db = getDatabase(app); const starCountRef = ref(db, 'testData'); onValue(starCountRef, (snapshot) => { const data = snapshot.val(); setTextData( Object.entries(data || {}).map( ([key, value]: [key: string, value: any]) => ({ key, text: value?.text, }) ) ); }); };
验证方法
修改完成后本地执行生产构建命令npm run build,构建完成后执行npm start启动生产服务,验证Realtime Database读取功能正常,控制台无emptyChildrenSingleton is not defined、Cannot read properties of undefined (reading 'syncPointTree_')报错即可。
内容的提问来源于stack exchange,提问作者Loudrous
相关产品推荐
相关产品推荐

