自定义您的 Auth 依赖项

Firebase JS SDK 的模块化设计可让您更好地控制应用的构建方式。这种灵活性可让您为平台定制依赖项,并通过剥离不需要的功能来优化软件包大小。

有两种方法来初始化 Auth 库:getAuth() 函数和 initializeAuth() 函数。第一种方法“getAuth()”提供了一切所需的内容,让应用可以充分利用 Auth 库可以提供的所有功能。这种方法的缺点是,它会提取大量可能不会被应用使用的代码。此外,还可能会提取您的目标平台不支持的代码,从而导致错误。为了避免这些问题,您可以使用 initializeAuth(),它接受一个依赖项映射作为参数。getAuth() 函数简单地使用指定的所有依赖项来调用 initializeAuth()。为便于说明,我们在下面提供的示例等同于浏览器环境中的 getAuth()

import {initializeAuth, browserLocalPersistence, browserPopupRedirectResolver, browserSessionPersistence, indexedDBLocalPersistence} from "firebase/auth";
import {initializeApp} from "firebase/app";

const app = initializeApp({/** Your app config */});
const auth = initializeAuth(app, {
  persistence: [indexedDBLocalPersistence, browserLocalPersistence, browserSessionPersistence],
  popupRedirectResolver: browserPopupRedirectResolver,
});

定制依赖项

并非所有应用都使用 signInWithPopupsignInWithRedirect 系列的函数。许多应用并不需要 indexedDB 提供的灵活性,也不需要同时支持 indexedDBlocalStorage,以防其中一个不可用。在这些情况下,默认的 getAuth() 会包含大量用不上的代码,增加了软件包的大小。作为替代,这些应用可以定制其依赖项。例如,如果您的应用仅使用电子邮件链接身份验证并且 localStorage 充足(由于您未使用 Web 或 Service Worker 脚本),则可以按照以下方式初始化 Auth,从而剥离大量多余的代码:

import {initializeAuth, browserLocalPersistence} from "firebase/auth";
import {initializeApp} from "firebase/app";

const app = initializeApp({/** Your app config */});
const auth = initializeAuth(app, {
  persistence: browserLocalPersistence,
  // No popupRedirectResolver defined
});

使用此代码,您移除了应用不需要的三个大型依赖项,从而显著减少用户访问您的网站时使用的带宽量。

针对具体平台的注意事项

在许多情况下,您需要手动定义 Auth 依赖项以避免初始化出错。getAuth() 函数假定使用某个特定平台。对于默认入口点,即为浏览器环境;对于 Cordova 入口点,即为 Cordova 环境。但是在某些情况下,您的特定应用的需求与这些假设冲突。例如,对于 Web 和 Service Worker 脚本,默认 getAuth() 实现会引入从 window 对象读取数据的代码,这会导致错误。在这些情况下,您必须定制依赖项。以下代码适用于在 Service Worker 上下文中初始化 Auth 库:

import {initializeAuth, indexedDBLocalPersistence} from "firebase/auth";
import {initializeApp} from "firebase/app";

const app = initializeApp({/** Your app config */});
const auth = initializeAuth(app, {
  persistence: indexedDBLocalPersistence,
  // No popupRedirectResolver defined
});

此代码指示 Auth 使用 indexedDB 持久性(在工作器上下文中可用)进行初始化,并省略 popupRedirectResolver 依赖项(该依赖项假定存在 DOM 上下文)。

此外还存在其他一些原因,导致您需要在某些平台上手动定义依赖项。在某些情况下,通过在 Auth 初始化中定义 popupRedirectResolver 字段,该库可以在初始化过程中执行额外的工作。在移动浏览器中,该库会提前向您的 Auth 网域打开 iframe。这样做是为了向大多数用户提供无缝的体验,但会在应用正在启动时加载额外的代码,从而影响性能。使用 initializeAuth() 并手动将 browserPopupRedirectResolver 依赖项传递给需要它的函数,可以避免此行为:

import {initializeAuth, browserLocalPersistence, browserPopupRedirectResolver, indexedDBLocalPersistence, signInWithRedirect, GoogleAuthProvider} from "firebase/auth";
import {initializeApp} from "firebase/app";

const app = initializeApp({/** Your app config */});
const auth = initializeAuth(app, {
  persistence: [indexedDBLocalPersistence, browserLocalPersistence],
});

// Later
signInWithRedirect(auth, new GoogleAuthProvider(), browserPopupRedirectResolver);

如果我们在 initializeAuth() 的依赖项中提供了 browserPopupRedirectResolver,则在对 signInWithRedirect() 的调用中,不再需要第三个参数。但是,通过将该依赖项直接移到对 signInWithRedirect() 的调用中,可以在初始化期间避免对性能的影响。在移动依赖项时需要做出权衡,但重点在于,您能够通过手动初始化库来作出与这些权衡有关的决策。

何时使用自定义初始化

重复一下,自定义初始化可让您更好地控制应用的 Auth SDK 使用情况。标准的 getAuth() 函数非常适合入门,适用于大多数用例。对于大多数应用来说,你可能只需要 getAuth()。但是,有很多原因导致您可能需要(或需要)改用手动式依赖项管理:

  • 对于软件包大小和加载时间极为重要的应用,自定义 Auth 初始化可能会减少很多个 KB 的数据。此外,您还可以通过将依赖项移到要使用的时间(而不是初始化时间)来缩短初始加载时间。
  • 对于在非 DOM 上下文(如 Web 和 Service Worker)中运行的代码,必须使用 initializeAuth() 以避免错误。