アプリを 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 コンソールで)自分で作成および構成したプロジェクトのことです。

実際のプロジェクトには、データベース インスタンス、ストレージ バケット、関数など、その Firebase プロジェクト用にセットアップしたリソースのライブリソースが含まれています。

実際の Firebase プロジェクトを使用する場合、対応しているプロダクトの一部またはすべてに対してエミュレータを実行できます。

エミュレートしていないプロダクトに関しては、アプリとコードはライブリソース(データベース インスタンス、ストレージ バケット、関数など)とやり取りします。

デモ

デモ Firebase プロジェクトには、実際の Firebase 構成がなく、ライブリソースもありません。これらのプロジェクトには通常、Codelab またはその他のチュートリアルを介してアクセスします。

デモ プロジェクトのプロジェクト ID には demo- という接頭辞が付いています。

デモ Firebase プロジェクトを使用する場合、アプリとコードはエミュレータのみとやり取りします。エミュレータが実行されていないリソースとアプリがやり取りしようとすると、コードは失敗します。

可能な限り、デモ プロジェクトを使用することをおすすめします。次のような利点があります。

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

アプリを計測可能にしてエミュレータと通信する

起動時、Cloud Firestore エミュレータは firebase.json ファイルfirestore 構成ごとに、デフォルト データベースと名前付きデータベースを作成します。

また、名前付きデータベースは、特定のデータベースを参照するエミュレータへの SDK または REST API 呼び出しに応じて暗黙的に作成されます。このような暗黙的に作成されたデータベースは、オープンルールで動作します。

Emulator Suite UI でデフォルト データベースと名前付きデータベースをインタラクティブに操作するには、ブラウザのアドレスバーで URL を更新して、デフォルト データベースまたは名前付きデータベースを選択します。

  • たとえば、デフォルト インスタンス内のデータをブラウジングするには、URL を localhost:4000/firestore/default/data に更新します。
  • ecommerce という名前のインスタンス内のデータをブラウジングするには、localhost:4000/firestore/ecommerce/data に更新します。

Android、Apple プラットフォーム、Web の各 SDK

次のように、Cloud Firestore とやり取りするようにアプリ内構成またはテストクラスを設定します。次のサンプルでは、アプリコードがデフォルトのプロジェクト データベースに接続しています。デフォルト データベース以外の追加の Cloud Firestore データベースに関する例については、複数のデータベースのガイドをご覧ください。

Kotlin+KTX
// 10.0.2.2 is the special IP address to connect to the 'localhost' of
// the host computer from an Android emulator.
val firestore = Firebase.firestore
firestore.useEmulator("10.0.2.2", 8080)

firestore.firestoreSettings = firestoreSettings {
    isPersistenceEnabled = false
}
Java
// 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);
Swift
let settings = Firestore.firestore().settings
settings.host = "127.0.0.1:8080"
settings.cacheSettings = MemoryCacheSettings()
settings.isSSLEnabled = false
Firestore.firestore().settings = settings

Web

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

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

Web

// Firebase previously initialized using firebase.initializeApp().
var db = firebase.firestore();
if (location.hostname === "localhost") {
  db.useEmulator("127.0.0.1", 8080);
}

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

Admin SDK

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

export FIRESTORE_EMULATOR_HOST="127.0.0.1:8080"

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

Admin SDK コードを別の環境で実行されている共有エミュレータに接続する場合は、Firebase CLI で設定したのと同じプロジェクト ID を指定する必要があります。プロジェクト ID を initializeApp に直接渡すか、GCLOUD_PROJECT 環境変数を設定することによって指定できます。

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

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

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

適切なメソッドで、次のエンドポイントに Firebase プロジェクト ID(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 for Firebase エミュレータを使用すると、実行中のエミュレータ インスタンスからデータをエクスポートできます。単体テストまたは継続的インテグレーション ワークフローで使用するデータのベースライン セットを定義し、チーム間で共有するためにエクスポートします。

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 Security Rules の評価トレースを行うことができます。

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

Cloud Firestore の複数データベースのサポート

現在、Emulator Suite UI は、デフォルト データベースに対するインタラクティブな作成、編集、削除、リクエストのモニタリング、セキュリティの可視化をサポートしていますが、追加の名前付きデータベースに対するサポートしていません。

ただしエミュレータ自体は、firebase.json ファイルの構成に基づいて、あるいは SDK または REST API 呼び出しに応じて暗黙的に、名前付きデータベースを作成します。

トランザクション

エミュレータは現在のところ、本番環境で発生するトランザクションの動作すべてを実装しているわけではありません。1 つのドキュメントに対して複数の書き込みが同時に実行される機能をテストする場合、エミュレータでは書き込みリクエストが完了するまで時間がかかることがあります。場合によっては、ロックが解除されるまでに最長で 30 秒かかります。必要に応じて、この問題に対応するように、テストのタイムアウトを調整することを検討してください。

インデックス

このエミュレータでは複合インデックスは追跡されず、有効なクエリであればそのまま実行されます。実際の Cloud Firestore インスタンスでアプリをテストし、必要なインデックスを特定してください。

上限

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

次のステップ