Auth の依存関係のカスタマイズ

Firebase JS SDK はモジュラー型の設計になっているため、アプリの構築方法を細かく制御できます。この柔軟性により、プラットフォームに合わせて依存関係を調整することができます。また、不要な機能を取り除くことでバンドルサイズを最適化できます。

Auth ライブラリを初期化するには、getAuth() 関数と initializeAuth() 関数の 2 つの方法があります。1 つ目の 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,
});

依存関係を調整する

すべてのアプリで signInWithPopup または signInWithRedirect ファミリーの関数が使用されるわけではありません。多くのアプリでは indexedDB が提供する柔軟性は必要ありません。また、indexedDBlocalStorage のどちらかが使用できない場合は、両方をサポートする必要はありません。このような場合、デフォルトの getAuth() には使用されないコードが多く含まれることになり、無意味にバンドルサイズを増大させてしまいます。そのような状況を回避するために、アプリで依存関係を調整できます。たとえば、アプリでメールリンク認証のみを使用し、ウェブワーカーまたはサービス ワーカーのスクリプトを使用していないため localStorage で十分であれば、次のように 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
});

このコードでは、アプリで不必要な 3 つの大きな依存関係が取り除かれ、ユーザーがサイトにアクセスするときに使用される帯域幅が大幅に削減されます。

プラットフォーム固有の考慮事項

多くの場合、初期化時のエラーを回避するため、Auth 依存関係を手動で定義する必要があります。getAuth() 関数は特定のプラットフォームを前提としています。デフォルトのエントリ ポイントではブラウザ環境を前提とし、Cordova エントリ ポイントでは Cordova 環境を前提としています。しかし、特定のアプリケーションのニーズはこうした前提と矛盾することがあります。たとえば、ウェブワーカーとサービス ワーカーのスクリプトの場合、getAuth() のデフォルトの実装では window オブジェクトから読み取るコードが取り込まれるため、エラーが発生します。そのような場合は依存関係を調整する必要があります。サービス ワーカーのコンテキストで 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
});

このコードは、indexedDB 永続性(ワーカーのコンテキストで利用可能)を使用して初期化するよう Auth に指示し、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() の呼び出しの 3 番目のパラメータは必要ありませんでした。この依存関係を signInWithRedirect() の呼び出しに直接移動することで、初期化時のパフォーマンスへの影響が除去されます。依存関係の移動にはトレードオフがありますが、重要な点は、ライブラリを手動で初期化する場合はそれらのトレードオフについて自ら判断できるということです。

カスタム初期化を使用する場面

まとめると、カスタム初期化ではアプリでの Auth SDK の使用を細かく制御できます。標準的な getAuth() 関数は、初めて使用する場合に適しており、ほとんどのユースケースで使用できます。ほとんどのアプリでは getAuth() があれば十分です。ただし、さまざまな理由によって、依存関係の手動管理に切り替えるのが望ましい(または切り替える必要がある)ことがあります。

  • バンドルのサイズと読み込み時間が極めて重要なアプリの場合、カスタム Auth 初期化により、何キロバイトものデータを削減できる可能性があります。また、依存関係を初期化時ではなく使用時に移動することで、初期化時の読み込み時間を短縮できます。
  • DOM 以外のコンテキスト(ウェブワーカーやサービス ワーカーなど)で実行されるコードでは、initializeAuth() を使用してエラーを回避する必要があります。