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

Firebase App未初始化:Nuxt插件与中间件的适配问题

问题:Nuxt服务端Firebase Admin初始化与中间件调用冲突

我编写了一个名为firebase.server.ts的Nuxt服务端插件,用于初始化Firebase Admin,代码如下:

import { initializeApp, cert, getApp } from "firebase-admin/app";

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig();

  if (!getApp()) {
    initializeApp({
      credential: cert("./service-account.json"),
      databaseURL: config.public.databaseURL,
    });
  }
});

同时还有一个名为apiauth.ts的认证中间件,用于验证API请求的Auth令牌,代码如下:

import { getAuth } from "firebase-admin/auth";

export default defineEventHandler(async (event: any) => {
  if (getRequestPath(event).startsWith("/api/")) {
    // First Check - Check for AUTH token:
    const authToken = getRequestHeader(event, "authorization")?.split(" ")[1];
    if (!authToken) {
      return {
        success: false,
        type: "api",
        error: "All API requests require a authorization token to be valid.",
      };
    }

    const auth = getAuth();
    // Second Check - Check is a valid AUTH token
    try {
      const tokenVerify = await auth.verifyIdToken(authToken);
      event.authUserConfirm = tokenVerify;
    } catch (error) {
      return {
        success: false,
        type: "api",
        error: "Invalid API token, could be expired or incorrect.",
      };
    }
  }
});

原本认为插件会优先完成Firebase实例初始化,中间件可直接调用相关服务,但实际出现错误:The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.。请问除了在中间件中再次添加初始化代码外,有没有更优的解决方法?


优化解决方案

1. 修正Firebase应用存在性检查逻辑

原插件中!getApp()的判断会在无默认应用时直接抛出异常,导致初始化逻辑无法执行。改用getApps()判断已初始化应用的数量,避免异常阻断流程:

// 修改后的firebase.server.ts
import { initializeApp, cert, getApps } from "firebase-admin/app";

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig();

  // 仅当无已初始化应用时才执行初始化
  if (getApps().length === 0) {
    initializeApp({
      credential: cert("./service-account.json"),
      databaseURL: config.public.databaseURL,
    });
  }
});

2. 提升插件执行优先级

在nuxt.config.ts中显式设置插件的最高优先级,确保它在所有中间件之前执行:

export default defineNuxtConfig({
  plugins: [
    { 
      src: '~/plugins/firebase.server.ts', 
      mode: 'server', 
      priority: 1000 // 数值越高,执行时机越早
    }
  ]
})

3. 将Firebase服务注入Nuxt上下文(推荐)

在插件中初始化并注入Firebase Auth服务到Nuxt上下文,中间件直接从上下文获取实例,彻底避免初始化顺序和重复调用问题:

// 修改后的firebase.server.ts
import { initializeApp, cert, getApps, getApp } from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig();

  if (getApps().length === 0) {
    initializeApp({
      credential: cert("./service-account.json"),
      databaseURL: config.public.databaseURL,
    });
  }

  // 获取已初始化的Auth服务并注入上下文
  const firebaseAuth = getAuth(getApp());
  return {
    provide: {
      firebaseAuth
    }
  };
});
// 修改后的apiauth.ts
export default defineEventHandler(async (event: any) => {
  if (getRequestPath(event).startsWith("/api/")) {
    const authToken = getRequestHeader(event, "authorization")?.split(" ")[1];
    if (!authToken) {
      return {
        success: false,
        type: "api",
        error: "All API requests require a authorization token to be valid.",
      };
    }

    // 从Nuxt上下文获取已初始化的Auth服务
    const { firebaseAuth } = useNuxtApp(event);
    try {
      const tokenVerify = await firebaseAuth.verifyIdToken(authToken);
      event.authUserConfirm = tokenVerify;
    } catch (error) {
      return {
        success: false,
        type: "api",
        error: "Invalid API token, could be expired or incorrect.",
      };
    }
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:12:52