Firebase JavaScript SDK 最佳实践

本页针对在使用 Firebase JavaScript SDK 时可能会遇到的 JavaScript 问题提供提示和问题排查方法。

还有其他难题或未找到您的问题?请查看 Firebase 的主要常见问题解答,详细了解针对整个 Firebase 以及特定产品的常见问题解答。

您还可以查看 Firebase JavaScript SDK GitHub 代码库,获取已报告问题和问题排查的最新列表,并在其中提交您自己的问题。

Node.js 的 Admin SDK 结构与 Firebase JavaScript SDK 不兼容

Node.js 的 Firebase Admin SDKFirebase JavaScript SDK 是不同的实现,它们不共享接口、类或函数定义。Admin SDK 对象的实例与 Firebase JavaScript SDK 函数不兼容。

例如,传递给 Firebase JavaScript SDK getDatabase 函数的 Admin SDKFirebaseApp 实例会产生以下错误:

TypeError: Cannot read properties of undefined (reading 'getProvider')
 at _getProvider
 at getDatabase

这适用于整个 Firebase JavaScript SDK API 接口,不仅仅是 Realtime Database。反之亦然。如果尝试将 Cloud Firestore JS SDK 的 Timestamp 类型与 Node.js 的 Firebase Admin SDK 结合使用,也会产生类似的错误。

避免使用冲突的 Firebase JavaScript SDK 版本

如果在项目中将多个冲突的 Firebase JavaScript SDK 版本配置为依赖项,当 SDK 实例在 SDK 软件包之间传递时,会导致运行时错误。例如,将 Data Connect 库与不匹配的 FirebaseApp 版本搭配使用会导致以下错误:

Error: Component data-connect has not been registered yet

此问题通常是由于只更新了部分 Firebase SDK 软件包的依赖项引起的。当自动依赖项更新工具更改项目的 yarn.lockpackage-lock.json 文件中的 Firebase SDK 依赖项的子集时,通常会发生这种情况。由于许多 Firebase JavaScript SDK 相互协同工作,因此使用不同版本的 SDK 会导致运行时不兼容,

如需解决此问题,请删除项目中的 node_modules/ 目录和 yarn.lock(对于 yarn)或 package-lock.json(对于 npm)并重新安装依赖项。

如果错误仍然存在,请使用 npm ls 命令进一步调试问题。这将记录项目的依赖项,以便您可以识别 firebase 模块的冲突版本。

例如,以下日志显示 package-using-older-firebase 导入了冲突的 Firebase JavaScript SDK 版本:

$ npm ls firebase --all
your-app@0.0.0
├── firebase@11.2.0
├─┬ @angular/fire@19.0.0
│ ├── firebase@11.2.0 deduped
│ └─┬ rxfire@6.1.0
│   └── firebase@10.14.1 deduped
└─┬ package-using-older-firebase@0.1.0
  └─── firebase@10.14.1

在应用中混用 CJS 和 ESM 的 requireimport 语句也可能会导致错误。这会创建多个 Firebase JavaScript SDK 实例,每个实例都互不相同,从而破坏 Firebase JavaScript SDK 互操作性。您可以提高所选打包器的详细程度,以调试此场景。例如,您可以使用 esbuild analyze 标志来实现此目的。

确保 Service Worker 已打包

Service Worker 通常是通过与 Web 应用的其余部分不同的管道构建的,并且不包含在 Webpack 等打包器的默认配置中。

如果您在 Service Worker 中使用 Firebase JavaScript SDK 的模块化版本,请务必将应用打包器配置为包含 Service Worker 源文件。以下示例使用 npx 在项目的 src 目录中打包 firebase-sw.js Service Worker:

npx esbuild ./src/firebase-sw.js --bundle --minify --main-fields=webworker,browser,module,main,default --outfile=public/firebase-sw.js

如果未打包的 Service Worker 导入不支持 Service Worker 的 ES 模块或 Service Worker 作用域中不存在的文件,则其激活操作将失败。有时,这些失败是静默的,因此难以调试。

如需详细了解如何将 Firebase JavaScript SDK 的模块化版本打包到您的应用中,请参阅将模块打包器与 Firebase 搭配使用

或者,您也可以从 CDN 导入 compat Firebase JavaScript SDK 软件包,从而无需进行打包:

// Give the service worker access to Firebase Messaging.
// Replace 10.13.2 with the version of the Firebase JS SDK you're using
// in your app.
importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-messaging-compat.js');

// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
firebase.initializeApp({
  ...
});

// Retrieve an instance of Firebase Messaging so that it can handle
// background messages.
const messaging = firebase.messaging();

使用服务器端渲染时,请使用 FirebaseServerApp

Firebase JavaScript SDK 最初设计为在浏览器环境中运行。服务器端呈现 (SSR) 框架的引入将 SDK 的使用场景扩展到了新的运行时环境。这些运行时提供网络浏览器提供的部分工具和 API。

例如,某些 Firebase SDK 需要使用 IndexedDB(仅限浏览器的 API)进行数据缓存。Firebase Auth 可能需要在某些登录流程中进行用户互动,而这在无头服务器环境中是不可能的。App Check 依赖于浏览器启发式方法,以便在创建 App Check 令牌之前验证用户。

在这些新环境中使用 SDK 时,请使用 FirebaseServerApp,这是 FirebaseApp 的一种新变体,可提供从客户端收集的数据来预加载 SSR Firebase 实例的方法。

FirebaseServerApp 支持两个参数:

  • Auth ID 令牌:如果提供,Firebase Auth 会自动让之前经过身份验证的用户登录,这可能会跨越 CSR/SSR 的会话边界。
  • App Check 令牌:如果提供,其他 Firebase SDK 会使用该令牌,而无需初始化 App Check 客户端实例(浏览器环境外不支持)。这会为启用了 App Check 的产品(例如 Cloud FunctionsData ConnectCloud FirestoreRealtime Database 和 Vertex AI)解除对 SSR 的支持。

如需查看 Next.js 中 FirebaseServerApp 的用法示例,请参阅使用 FirebaseServerApp 简化 SSR 应用开发