ウェブ向け Firebase について理解する

Firebase でウェブアプリを開発しているときに、なじみのないコンセプトに直面することや、プロジェクトに関して適切な判断を下すために、より多くの情報を必要とする分野に遭遇することがあります。このページでは、このような質問への回答や、詳細を説明するリソースの紹介を行っています。

このページで扱っていないトピックについて不明点がある場合は、オンライン コミュニティをご覧ください。また、定期的に新しいトピックを追加していますので、このページをチェックして最新情報をご確認ください。

SDK バージョン: 名前空間方式とモジュラー

Firebase には、ウェブアプリ用に 2 つの API サーフェスが用意されています。

  • JavaScript - 名前空間方式。これは数年前から Firebase で管理されている JavaScript インターフェースであり、これまで Firebase アプリを扱ってきたウェブ デベロッパーにはお馴染みのバージョンです。名前空間方式 API では新機能がサポートされなくなるため、新しいアプリではモジュラー API を採用する必要があります。
  • JavaScript - モジュラー。この SDK はモジュラー アプローチをベースにしています。webpackRollup など、モダンな JavaScript ビルドツールを使用することにより、SDK のサイズが小さくなり、効率も高まります。

モジュラー API では、アプリで使用されていないコードを取り除くビルドツールの恩恵を受けることができます。このプロセスは「ツリー シェイキング」と呼ばれます。この SDK を使用してアプリをビルドすると、サイズが大幅に削減されます。名前空間方式 API もモジュールとして提供されていますが、厳密な意味ではモジュール構造ではなく、同程度のサイズ削減は実現できません。

モジュラー API の大部分は名前空間方式 API と同じパターンに従いますが、コードの記述方法は異なります。一般的に、名前空間方式 API は名前空間とサービス パターンを指向しているのに対し、おジュール方式 API は個別の関数を指向しています。たとえば、名前空間方式 API のドットチェーン(firebaseApp.auth() など)は、モジュラー API では firebaseApp を受け取って Authentication インスタンスを返す単一の getAuth() 関数に置き換えられています。

つまり、名前空間方式 API を使用して作成されたウェブアプリで、モジュラー アプリ設計のメリットを利用するには、リファクタリングが必要になります。詳細については、アップグレード ガイドをご覧ください。

JavaScript - 新しいアプリ用のモジュラー API

Firebase との統合を新たに開始する場合は、SDK を追加して初期化する際に、モジュラー API を選択できます。

アプリを開発する際には、原則としてfunctionsを中心にコードを記述することになります。モジュラー API では最初の引数としてサービスが渡され、関数がサービスの詳細を使用して残りの処理を行います。次に例を示します。

import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
  // Check for user status
});

その他の例と詳細については、各プロダクトのガイドと、モジュラー API のリファレンス ドキュメントをご覧ください。

ウェブ SDK をアプリに追加する方法

Firebase には、Remote ConfigFCM など、ほとんどの Firebase プロダクトの JavaScript ライブラリが用意されています。Firebase SDK をウェブアプリに追加する方法は、どのツールをアプリで使用しているか(例: モジュール バンドラなど)によって異なります。

使用可能なライブラリは、次のサポートされるメソッドを介してアプリに追加できます。

  • npm(モジュール バンドラ用)
  • CDN(コンテンツ配信ネットワーク)

設定手順について詳しくは、Firebase を JavaScript アプリに追加するをご覧ください。このセクションの残りの部分では、利用可能なオプションを選択するうえで役立つ情報を記載しています。

npm

Firebase npm パッケージにはブラウザと Node.js の両方のバンドルが含まれており、これをダウンロードして Firebase SDK のローカルコピーを入手できます。このコピーは、Node.js アプリ、React Native、Electron などのブラウザ以外のアプリケーションで必要になる場合があります。ダウンロードには、一部のパッケージのオプションとして Node.js と React Native のバンドルが含まれています。Node.js のバンドルは、SSR フレームワークのサーバー側レンダリング(SSR)のステップで必要です。

npm を webpackRollup などのモジュール バンドラで使用すると、最適化オプションで未使用のコードを「ツリー シェイキング」し、対象とするポリフィルを適用して、アプリのサイズを大幅に削減できます。これらの機能を実装すると、構成やビルドチェーンが複雑になる恐れがありますが、さまざまなメインストリーム CLI ツールを使用して複雑さを軽減できます。これらのツールには、AngularReactVueNext などがあります。

まとめると、次のとおりです。

  • アプリサイズの有効な最適化を実現
  • 堅牢なツールを活用してモジュールを管理
  • Node.js を使用する SSR の場合は必須

CDN(コンテンツ配信ネットワーク)

多くのデベロッパーになじみのあるシンプルな SDK セットアップ メソッドとして、Firebase の CDN に保存されているライブラリを追加する方法があります。CDN を使用して SDK を追加する場合、ビルドツールが不要になり、モジュール バンドラと比較してビルドチェーンがシンプルで作業しやすくなる傾向があります。アプリのインストール サイズが特に重要ではなく、TypeScript からのトランスパイルといった特別な要件がなければ、CDN が最適な選択肢と言えます。

まとめると、次のとおりです。

  • 一般的かつシンプル
  • アプリのサイズが特に重要ではない場合に適している
  • ウェブサイトでビルドツールを使用しない場合に適している

Firebase のウェブ SDK のバリアント

Firebase のウェブ SDK はブラウザ アプリケーションとノード アプリケーションの両方で使用できます。ただし、一部のプロダクトはノード環境では使用できません。サポートされる環境のリストをご覧ください。

プロダクト SDK によっては、ブラウザとノードに別々のバリアントがあり、それぞれが ESM と CJS の両方のフォーマットで提供されることもあれば、Cordova や React Native のバリアントを提供していることもあります。Web SDK は、ツールの構成または環境に基づいて正しいバリアントを提供するように構成されており、通常は、手動で選択する必要はありません。すべての SDK バリアントは、Node.js デスクトップや IoT アプリケーションなどのエンドユーザー アクセスのウェブアプリやクライアント アプリを構築しやすいように設計されています。特権環境(サーバーなど)からの管理者権限を設定することが目標の場合は、代わりに Firebase Admin SDK を使用してください。

バンドラとフレームワークによる環境検出

npm を使用して Firebase Web SDK をインストールすると、JavaScript バージョンと Node.js バージョンの両方がインストールされます。このパッケージには、アプリケーションに適したバンドルを有効にするための詳細な環境検出機能が含まれています。

コードで Node.js の require ステートメントを使用する場合、SDK は Node 固有のバンドルを検索します。それ以外の場合は、package.json ファイルで適切なエントリ ポイント フィールド(mainbrowsermodule など)を検出できるように、バンドラが適切に設定されている必要があります。SDK でランタイム エラーが発生した場合は、環境に適したバンドルのタイプを優先するようにバンドラが構成されていることを確認してください。

Firebase 構成オブジェクトの詳細

アプリで Firebase を初期化するには、アプリの Firebase プロジェクト構成を提供する必要があります。Firebase 構成オブジェクトの入手ははいつでもできます。

  • 構成オブジェクト(特に、必須の Firebase オプション apiKeyprojectIdappID)を手動で編集しないことをおすすめします。これらの必須の「Firebase オプション」のいずれかで無効な値が指定されている、または値が欠落している状態でアプリを初期化すると、ユーザーに深刻な問題が発生することがあります。 ただし、authDomain は例外です。これは、signInWithRedirect の使用に関するベスト プラクティスに沿って更新できます。

  • Firebase プロジェクトで Google Analytics を有効にすると、構成オブジェクトに measurementId フィールドが含まれます。このフィールドの詳細については、Analytics のスタートガイドページをご覧ください。

  • Firebase ウェブアプリの作成後にGoogle Analytics または Realtime Database を有効にする場合は、関連する構成値(それぞれ measurementIddatabaseURL)に適切な値が設定された最新の Firebase 構成オブジェクトをアプリで使用していることを確認してください。Firebase 構成オブジェクトはいつでも入手できます。

すべてのサービスが有効になっている構成オブジェクトの形式は次のとおりです(これらの値は自動的に入力されます)。

var firebaseConfig = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  // The value of `databaseURL` depends on the location of the database
  databaseURL: "https://DATABASE_NAME.firebaseio.com",
  projectId: "PROJECT_ID",
  // The value of `storageBucket` depends on when you provisioned your default bucket (learn more)
  storageBucket: "PROJECT_ID.firebasestorage.app",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  // For Firebase JavaScript SDK v7.20.0 and later, `measurementId` is an optional field
  measurementId: "G-MEASUREMENT_ID",
};

使用可能なライブラリ

その他の設定オプション

Firebase SDK の読み込みを遅らせる(CDN から)

ページ全体が読み込まれるまで、Firebase SDK の登録を遅らせることができます。<script type="module"> でモジュール方式 API CDN スクリプトを使用している場合は、これがデフォルトの動作です。名前空間方式の CDN スクリプトをモジュールとして使用する場合は、次の手順で読み込みを遅らせます。

  1. Firebase SDK の各 script タグに defer フラグを追加して、2 番目のスクリプトを使用して Firebase の初期化を遅らせます。

    <script defer src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script>
    
    <script defer src="https://www.gstatic.com/firebasejs/8.10.1/firebase-auth.js"></script>
    <script defer src="https://www.gstatic.com/firebasejs/8.10.1/firebase-firestore.js"></script>
    
    // ...
    
    <script defer src="./init-firebase.js"></script>
    
  2. init-firebase.js ファイルを作成して、以下を含めます。

    // TODO: Replace the following with your app's Firebase project configuration
    var firebaseConfig = {
      // ...
    };
    
    // Initialize Firebase
    firebase.initializeApp(firebaseConfig);
    

1 つのアプリで複数の Firebase プロジェクトを使用する

ほとんどの場合、Firebase の初期化は単一のデフォルト アプリで行うだけで済みます。このアプリからは 2 つの方法で Firebase にアクセスできます(この 2 つの方法は同等です)。

Web

import { initializeApp } from "firebase/app";
import { getStorage } from "firebase/storage";
import { getFirestore } from "firebase/firestore";

// Initialize Firebase with a "default" Firebase project
const defaultProject = initializeApp(firebaseConfig);

console.log(defaultProject.name);  // "[DEFAULT]"

// Option 1: Access Firebase services via the defaultProject variable
let defaultStorage = getStorage(defaultProject);
let defaultFirestore = getFirestore(defaultProject);

// Option 2: Access Firebase services using shorthand notation
defaultStorage = getStorage();
defaultFirestore = getFirestore();

Web

// Initialize Firebase with a "default" Firebase project
const defaultProject = firebase.initializeApp(firebaseConfig);

console.log(defaultProject.name);  // "[DEFAULT]"

// Option 1: Access Firebase services via the defaultProject variable
let defaultStorage = defaultProject.storage();
let defaultFirestore = defaultProject.firestore();

// Option 2: Access Firebase services using shorthand notation
defaultStorage = firebase.storage();
defaultFirestore = firebase.firestore();

ただし、複数の Firebase プロジェクトに同時にアクセスしなければならない場合もあります。たとえば、ある Firebase プロジェクトのデータベースからデータを読み取り、別の Firebase プロジェクトにファイルを保存することがあります。また、1 つのプロジェクトを認証し、もう一つのプロジェクトは未認証のままにする場合もあります。

Firebase JavaScript SDK を使用すると、プロジェクトごとに独自の Firebase 構成情報を使用し、1 つのアプリで同時に複数の Firebase プロジェクトを初期化して使用できます。

Web

import { initializeApp, getApp } from "firebase/app";
import { getStorage } from "firebase/storage";
import { getFirestore } from "firebase/firestore";

// Initialize Firebase with a default Firebase project
initializeApp(firebaseConfig);

// Initialize Firebase with a second Firebase project
const otherProject = initializeApp(otherProjectFirebaseConfig, "other");

console.log(getApp().name);  // "[DEFAULT]"
console.log(otherProject.name);    // "otherProject"

// Use the shorthand notation to access the default project's Firebase services
const defaultStorage = getStorage();
const defaultFirestore = getFirestore();

// Use the otherProject variable to access the second project's Firebase services
const otherStorage = getStorage(otherProject);
const otherFirestore = getFirestore(otherProject);

Web

// Initialize Firebase with a default Firebase project
firebase.initializeApp(firebaseConfig);

// Initialize Firebase with a second Firebase project
const otherProject = firebase.initializeApp(otherProjectFirebaseConfig, "other");

console.log(firebase.app().name);  // "[DEFAULT]"
console.log(otherProject.name);    // "otherProject"

// Use the shorthand notation to access the default project's Firebase services
const defaultStorage = firebase.storage();
const defaultFirestore = firebase.firestore();

// Use the otherProject variable to access the second project's Firebase services
const otherStorage = otherProject.storage();
const otherFirestore = otherProject.firestore();

開発用ローカル ウェブサーバーを実行する

ウェブアプリを作成する場合、Firebase JavaScript SDK の一部では、ウェブアプリがローカル ファイル システムではなく、サーバーから提供されている必要があります。Firebase CLI を使用してローカル サーバーを実行できます。

アプリに Firebase Hosting をすでに設定している場合は、以下の手順の一部をすでに完了させている場合があります。

ウェブアプリを提供するには、コマンドライン ツールである Firebase CLI を使用します。

  1. CLI をインストールする方法または最新バージョンに更新する方法については、Firebase CLI のドキュメントをご覧ください。

  2. Firebase プロジェクトを初期化します。ローカルアプリ ディレクトリのルートから次のコマンドを実行します。

    firebase init

  3. 開発用のローカル サーバーを起動します。ローカルアプリ ディレクトリのルートから次のコマンドを実行します。

    firebase serve

Firebase JavaScript SDK のオープンソース リソース

Firebase はオープンソース開発をサポートしているため、コミュニティへの貢献やフィードバックが推奨されています。

Firebase JavaScript SDK

ほとんどの Firebase JavaScript SDK は、一般公開されている Firebase GitHub リポジトリでオープンソース ライブラリとして開発されています。

クイックスタート サンプル

Firebase には、ウェブの Firebase API のほとんどのクイックスタート サンプルのコレクションがあります。これらのクイックスタートは、一般公開されている Firebase GitHub クイックスタート リポジトリで確認できます。Firebase SDK を使用するためのサンプルコードとして、このクイックスタートを使用することもできます。