アプリを Cloud Firestore エミュレータに接続する

アプリを Cloud Firestore エミュレータに接続する前に、Firebase Local Emulator Suite の全体的なワークフローを理解し、Local Emulator Suite のインストールと構成を行い、CLI コマンドを確認しておいてください。

Firebase プロジェクトを選択する

Firebase Local Emulator Suite は、1 つの Firebase プロジェクト向けにプロダクトをエミュレートします。

エミュレータを起動する前に CLI の作業ディレクトリで firebase use を実行し、使用するプロジェクトを選択します。または、各エミュレータ コマンドに --project フラグを渡すという方法もあります。

Local Emulator Suite は、実際の Firebase プロジェクトとデモ プロジェクトのエミュレーションをサポートしています。

プロジェクト タイプ 特長 エミュレータで使用
実際 実際のプロジェクトとは、Firebase コンソールで構成して有効にしたプロジェクトです。実際のプロジェクトには、そのプロジェクト用に設定したライブリソース(データベース、ストレージ バケット、関数など)が含まれています。 実際のプロジェクトを使用する場合は、プロジェクトでサポートされている一部またはすべてのプロダクト用としてエミュレータを実行できます。

エミュレートしていないプロダクトに関しては、アプリとコードはライブのデータベース、ストレージ バケット、関数などとやり取りします。
デモ デモ プロジェクトには Firebase コンソールの構成がなく、ライブリソースもありません。

デモ プロジェクトの ID には demo- という接頭辞が付いています。
デモ プロジェクトを使用する場合、アプリとコードはエミュレータのみとやり取りします。エミュレータが実行されていないリソースとアプリのやり取りが発生すると、そのコードは失敗します。

可能であれば、デモ プロジェクトを使用することをおすすめします。次のような特長があります。

  • Firebase プロジェクトを作成せずにエミュレータを実行できるため、セットアップが簡単である
  • エミュレートされていない(本番環境の)リソースを誤って呼び出しても、データが変更されたり、使用量がカウントされたり、課金が発生したりする可能性がないため、安全性が高い
  • インターネットにアクセスして SDK 構成をダウンロードする必要がないため、オフラインでも使いやすい

アプリをインストルメント化してエミュレータと通信する

Android、iOS、ウェブ SDK

次のように、Cloud Firestore とやり取りするようにアプリ内構成またはテストクラスを設定します。

Android
        // 10.0.2.2 is the special IP address to connect to the 'localhost' of
        // the host computer from an Android emulator.
        FirebaseFirestore firestore = FirebaseFirestore.getInstance();
        firestore.useEmulator("10.0.2.2", 8080);

        FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
                .setPersistenceEnabled(false)
                .build();
        firestore.setFirestoreSettings(settings);
iOS - Swift
let settings = Firestore.firestore().settings
settings.host = "localhost:8080"
settings.isPersistenceEnabled = false
settings.isSSLEnabled = false
Firestore.firestore().settings = settings

ウェブ バージョン 9

import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";

// firebaseApps previously initialized using initializeApp()
const db = getFirestore();
connectFirestoreEmulator(db, 'localhost', 8080);

ウェブ バージョン 8

// Firebase previously initialized using firebase.initializeApp().
var db = firebase.firestore();
if (location.hostname === "localhost") {
  db.useEmulator("localhost", 8080);
}
ウェブ
// Initialize your Web app as described in the Get started for Web
// Firebase previously initialized using firebase.initializeApp().
var db = firebase.firestore();
if (location.hostname === "localhost") {
  db.useEmulator("localhost", 8080);
}

エミュレータを使用して Firestore イベントによってトリガーされる Cloud Functions をテストするために、追加の設定は必要ありません。Firestore エミュレータと Cloud Functions エミュレータの両方が実行されている場合、これらは自動的に連携します。

Admin SDK

環境変数 FIRESTORE_EMULATOR_HOST が設定されている場合、Firebase Admin SDK は Cloud Firestore エミュレータに自動的に接続します。

export FIRESTORE_EMULATOR_HOST="localhost:8080"

コードを Cloud Functions エミュレータ内で実行している場合、initalizeApp を呼び出すとプロジェクト ID とその他の構成が自動的に設定されます。

他の環境から Cloud Firestore エミュレータに接続する場合は、プロジェクト ID を指定する必要があります。プロジェクト ID を initializeApp に直接渡すか、GCLOUD_PROJECT 環境変数を設定することによって指定できます。実際の Firebase プロジェクト ID を使用する必要はありません。Cloud Firestore エミュレータは、有効な形式である限り、どのようなプロジェクト ID でも受け入れます。

Node.js Admin SDK
admin.initializeApp({ projectId: "your-project-id" });
環境変数
export GCLOUD_PROJECT="your-project-id"

テスト間でデータベースをクリアする

Firestore の本番環境では、データベースをフラッシュするためのプラットフォーム SDK メソッドは提供されませんが、Firestore エミュレータでは、このための REST エンドポイントが提供されます。REST エンドポイントは、テストの開始前に、テストフレームワークの設定とティアダウン ステップ、テストクラス、またはシェル(curl などを使用)から呼び出すことができます。この方法は、単純にエミュレータ プロセスをシャットダウンする代わりに使用できます。

適切なメソッドで、次のエンドポイントに Firebase projectID(firestore-emulator-exampleなど)を指定して HTTP DELETE オペレーションを実行します。

"http://localhost:8080/emulator/v1/projects/firestore-emulator-example/databases/(default)/documents"

コードは通常、フラッシュが終了または失敗したことを REST が確認するまで待機します。

この操作はシェルから実行できます。

// Shell alternative…
$ curl -v -X DELETE "http://localhost:8080/emulator/v1/projects/firestore-emulator-example/databases/(default)/documents"

このようなステップが存在することで、テストを順番に行って関数をトリガーする際に、実行と実行の間に古いデータが消去され、新しいベースラインのテスト構成が使用されるようになります。

データのインポートとエクスポート

データベース エミュレータと Cloud Storage エミュレータを使用すると、実行中のエミュレータ インスタンスからデータをエクスポートできます。単体テストまたは継続的インテグレーション ワークフローで使用するデータのベースライン セットを定義し、チーム間で共有するためにエクスポートします。

firebase emulators:export ./dir

テストでは、エミュレータの起動時にベースライン データをインポートします。

firebase emulators:start --import=./dir

シャットダウン時にデータをエクスポートするようにエミュレータに指示するには、エクスポート パスを指定します。または、--import フラグに渡されたパスをそのまま使用することもできます。

firebase emulators:start --import=./dir --export-on-exit

データのインポートとエクスポートのこれらのオプションは、firebase emulators:exec コマンドでも機能します。詳細については、エミュレータ コマンド リファレンスをご参照ください。

セキュリティ ルールのアクティビティを可視化する

プロトタイプとテストのループを行うときに、Local Emulator Suite が提供する可視化ツールとレポートを使用できます。

リクエスト モニタリングを使用する

Cloud Firestore エミュレータを使用すると、Emulator Suite UI でクライアント リクエストを可視化できます。たとえば、Firebase セキュリティ ルールの評価トレースなどを行うことができます。

[Firestore] > [Requests] タブを開くと、各リクエストの詳細な評価シーケンスが表示されます。

セキュリティ ルールの評価を示す Firestore エミュレータのリクエスト モニタリング

ルール評価レポートを可視化する

プロトタイプにセキュリティ ルールを追加する際に、Local Emulator Suite のデバッグツールを使用してデバッグできます。

一連のテストを実行した後、それぞれのセキュリティ ルールの評価を示したテスト カバレッジ レポートにアクセスできます。

レポートを取得するには、エミュレータの実行中に公開されたエンドポイントに対してクエリを実行します。ブラウザでの表示に適したバージョンを参照するには、次の URL を使用します。

http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage.html

これによりルールが式やサブ式に分割されます。それぞれの式の上にマウスカーソルを重ねて、評価回数や返された値などの詳細情報を確認できます。このデータの未加工の JSON バージョンを取得するには、クエリに次の URL を含めます。

http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage

次の HTML バージョンのレポートでは、未定義のエラーと null 値のエラーをスローする評価がハイライト表示されます。

制限事項

Cloud Firestore エミュレータは、本番環境サービスの動作を忠実に再現しようとしますが、いくつか注意が必要な制限事項があります。

  • インデックス。このエミュレータでは複合インデックスは追跡されず、有効なクエリであればそのまま実行されます。実際の Cloud Firestore インスタンスでアプリをテストし、必要なインデックスを特定してください。
  • 制限。このエミュレータでは、本番環境で適用される制限すべてが適用されるわけではありません。たとえば、本番環境サービスではサイズが大きいことを理由に拒否されるトランザクションでも、エミュレータでは許容される場合があります。ドキュメントに記載されている制限を十分に理解し、事前にこうした制限を回避するようにアプリを設計してください。

次のステップ