You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决SvelteKit项目中Firebase初始化报window is not defined错误

解决SvelteKit中Firebase "window is not defined" 错误的两种方案

错误原因

SvelteKit默认启用服务端渲染(SSR),组件顶层代码会在服务端执行,但服务端环境不存在window对象。Firebase的部分模块(如Analytics)初始化时依赖window,直接在组件顶层执行初始化代码就会触发该错误。

方案一:无需onMount的条件初始化

通过判断浏览器环境延迟初始化Firebase,避开服务端执行阶段。同时将依赖window的Analytics模块单独处理,避免在服务端加载。

修改后的组件代码:

<script>
  import { initializeApp } from "firebase/app";
  import { getFirestore } from "firebase/firestore";
  import { collection, addDoc } from "firebase/firestore";
  // 延迟导入依赖window的模块
  let getAnalytics;

  let song = 'song';
  let app, db;

  const firebaseConfig = {
    // 你的Firebase配置
  };

  // 仅在浏览器环境初始化
  if (typeof window !== 'undefined') {
    // 动态导入Analytics
    import('firebase/analytics').then(module => {
      getAnalytics = module.getAnalytics;
    });
    app = initializeApp(firebaseConfig);
    db = getFirestore(app);
    // 可选:初始化Analytics(仅浏览器)
    if (getAnalytics) getAnalytics(app);
  }

  async function sendSong() {
    // 确保db已初始化再调用
    if (!db) return;
    try {
      const docRef = await addDoc(collection(db, "songs"), {
        title: song, // 修正原代码的对象包裹错误
        artist: "test" // 修正拼写错误
      });
      console.log("Document written with ID: ", docRef.id);
    } catch (e) {
      console.error("Error adding document: ", e);
    }
  }
</script>

<input bind:value={song}>
<button on:click={sendSong}>提交歌曲</button>

<style>
</style>

方案二:onMount初始化+全局Store共享(支持外部调用)

如果必须用onMount初始化,可以将Firebase实例存入Svelte Store,让组件内外都能访问。

步骤1:创建Firebase Store文件(src/lib/firebase.js)

import { writable } from 'svelte/store';
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAnalytics } from "firebase/analytics";

const firebaseConfig = {
  // 你的Firebase配置
};

export const firebaseStore = writable(null);

export function initFirebase() {
  const app = initializeApp(firebaseConfig);
  const db = getFirestore(app);
  const analytics = getAnalytics(app);
  firebaseStore.set({ app, db, analytics });
}

步骤2:在组件中使用

<script>
  import { onMount } from 'svelte';
  import { firebaseStore } from '$lib/firebase';
  import { collection, addDoc } from "firebase/firestore";

  let song = 'song';
  let db;

  // 订阅store获取db实例
  const unsubscribe = firebaseStore.subscribe(value => {
    if (value) db = value.db;
  });

  onMount(() => {
    import('$lib/firebase').then(module => {
      module.initFirebase();
    });
    return unsubscribe;
  });

  async function sendSong() {
    if (!db) return;
    try {
      const docRef = await addDoc(collection(db, "songs"), {
        title: song,
        artist: "test"
      });
      console.log("Document written with ID: ", docRef.id);
    } catch (e) {
      console.error("Error adding document: ", e);
    }
  }
</script>

<input bind:value={song}>
<button on:click={sendSong}>提交歌曲</button>

<style>
</style>

这种方式下,其他组件或模块只要导入firebaseStore就能获取已初始化的Firebase实例,实现跨组件共享。


内容的提问来源于stack exchange,提问作者pohadkove

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 01:45:34