SvelteKit集成Firebase AppCheck报错:document is not defined
错误信息
ReferenceError: document is not defined
at makeDiv (C:\Users...\ecomm\node_modules@firebase\app-check\dist\index.cjs.js:1149:24)
at initializeV3 (C:\Users...\ecomm\node_modules@firebase\app-check\dist\index.cjs.js:1094:17)
at ReCaptchaV3Provider.initialize (C:\Users...\ecomm\node_modules@firebase\app-check\dist\index.cjs.js:1294:9)
at _activate (C:\Users...\ecomm\node_modules@firebase\app-check\dist\index.cjs.js:1598:23)
at Proxy.initializeAppCheck (C:\Users...\ecomm\node_modules@firebase\app-check\dist\index.cjs.js:1554:5)
at C:/Users/.../ecomm/src/lib/firebase.ts:23:17
at async instantiateModule (file:///C:/Users/.../ecomm/node_modules/vite/dist/node/chunks/dep-1513d487.js:50330:9)
问题背景
该问题场景与React环境下的类似问题一致,但当前使用的是SvelteKit框架。
当前集成代码
import { initializeApp } from "firebase/app"; import { initializeAppCheck, ReCaptchaV3Provider } from "firebase/app-check"; const firebaseConfig = { /* the app config */ }; const app = initializeApp(firebaseConfig); const appCheck = initializeAppCheck(app, { provider: new ReCaptchaV3Provider('*my public key*'), isTokenAutoRefreshEnabled: true });
解决方案
原因分析
SvelteKit默认会在服务端和客户端都执行代码,而document是浏览器环境特有的对象,服务端渲染时不存在,因此初始化AppCheck时会触发错误。
解决步骤
仅在客户端初始化AppCheck
使用SvelteKit提供的browser环境变量,确保代码只在浏览器环境执行:import { initializeApp } from "firebase/app"; import { initializeAppCheck, ReCaptchaV3Provider } from "firebase/app-check"; import { browser } from '$app/environment'; const firebaseConfig = { /* the app config */ }; const app = initializeApp(firebaseConfig); if (browser) { const appCheck = initializeAppCheck(app, { provider: new ReCaptchaV3Provider('*my public key*'), isTokenAutoRefreshEnabled: true }); }动态导入Firebase AppCheck模块(可选)
通过动态导入方式,确保依赖浏览器API的模块仅在客户端加载,同时减少服务端打包体积:import { initializeApp } from "firebase/app"; import { browser } from '$app/environment'; const firebaseConfig = { /* the app config */ }; const app = initializeApp(firebaseConfig); if (browser) { const { initializeAppCheck, ReCaptchaV3Provider } = await import("firebase/app-check"); const appCheck = initializeAppCheck(app, { provider: new ReCaptchaV3Provider('*my public key*'), isTokenAutoRefreshEnabled: true }); }开发环境使用调试令牌
开发阶段可使用Firebase调试令牌,避免依赖ReCaptcha,同时支持服务端运行:import { initializeApp } from "firebase/app"; import { initializeAppCheck, ReCaptchaV3Provider } from "firebase/app-check"; import { browser, dev } from '$app/environment'; const firebaseConfig = { /* the app config */ }; const app = initializeApp(firebaseConfig); if (browser) { let provider = new ReCaptchaV3Provider('*my public key*'); if (dev) { // 替换为Firebase控制台生成的调试令牌 provider = new ReCaptchaV3Provider('your-debug-token'); // 开启调试模式(需在Firebase控制台配置允许调试) self.FIREBASE_APPCHECK_DEBUG_TOKEN = true; } const appCheck = initializeAppCheck(app, { provider, isTokenAutoRefreshEnabled: true }); }
关键说明
browser变量由SvelteKit提供,用于精准判断当前代码是否运行在浏览器环境。- 动态导入能避免服务端加载依赖浏览器API的模块,减少不必要的资源占用。
- 调试令牌仅用于开发环境,生产环境需切换为正式的ReCaptcha密钥。
内容的提问来源于stack exchange,提问作者Luigi Masdea

