firebase emulatorの設定と使用


概要

エミュレータの設定と、エミュレータを使った開発メモ

emulatorの設定

こちらに書いてあるので、詳細を説明するまでもありませんが、一応ポイントのみ解説
https://firebase.google.com/docs/emulator-suite/install_and_configure?hl=ja

予めインストールしておくもの

  • node (当たり前ですが)
  • Firebase CLI (npm i -g firebase-tools)
  • JDK 1.8以降

インストール

作業ディレクトリ (firebase initしてあるディレクトリ) で以下を実行

$ firebase init emulators

実行すると、どのエミュレータを設定するか聞かれるので、必要なものを選択する。
次にポート番号を求められるので特に別で使用しているポートなどがなければデフォルトのまま進む。
最後にエミュレータをダウンロードするか聞かれるのでYで進める
? Would you like to download the emulators now? Yes


     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

  /Users/path/directory

Before we get started, keep in mind:

  * You are initializing in an existing Firebase project directory


=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add, 
but for now we'll just set up a default project.

i  .firebaserc already has a default project, using <project id>.

=== Emulators Setup
? Which Firebase emulators do you want to set up? Press Space to select emulators, then Enter to confirm your choices. (Press <space> to select, <
a> to toggle all, <i> to invert selection)Authentication Emulator, Functions Emulator, Firestore Emulator, Pub/Sub Emulator
i  Port for auth already configured: 9099
i  Port for functions already configured: 5001
i  Port for firestore already configured: 8080
i  Port for pubsub already configured: 8085
i  Emulator UI already enabled with port: (automatic)
? Would you like to download the emulators now? Yes
i  ui: downloading ui-v1.4.2.zip...

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

✔  Firebase initialization complete!

成功したら、emulatorを開始する

$ firebase emulators:start

開始するとエミュレータのインストールが実行され、その後エミュレータが起動する。


functions % firebase emulators:start
i  emulators: Starting emulators: auth, functions, firestore, pubsub
⚠  functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: database, hosting
✔  functions: Using node@10 from host.
i  firestore: Firestore Emulator logging to firestore-debug.log
i  pubsub: Pub/Sub Emulator logging to pubsub-debug.log
i  ui: downloading ui-v1.4.2.zip...
Progress: =========================================================================================================================> (100% of 4MB
i  ui: Emulator UI logging to ui-debug.log
...

その後、functionsを使用している場合はエミュレータ上にfunctionがデプロイされる。
emulatorの準備が終わると以下のような表示になり、 localhost:4000 を叩くとemulator画面が表示される。

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://localhost:4000                │
└─────────────────────────────────────────────────────────────┘

┌────────────────┬────────────────┬─────────────────────────────────┐
│ Emulator       │ Host:Port      │ View in Emulator UI             │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Authentication │ localhost:9099 │ http://localhost:4000/auth      │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Functions      │ localhost:5001 │ http://localhost:4000/functions │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Firestore      │ localhost:8080 │ http://localhost:4000/firestore │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Pub/Sub        │ localhost:8085 │ n/a                             │
└────────────────┴────────────────┴─────────────────────────────────┘
  Emulator Hub running at localhost:4400
  Other reserved ports: 4500

Issues? Report them at https://githu

emulator UIにアクセスした状態

起動できたら control + Cで 一度終了する

emulatorへのアクセス

authでログイン、firestoreへの読み取りアクセス、functionの実行を行う。

auth emulator へのユーザ追加

ログイン用のユーザを追加する。
プログラム側で追加できるが、emulator UIを使ってユーザを追加できる。
emulator UI にアクセスし(ポートを変更していなければlocalhost:4000)、Authenticationの画面でユーザを追加できる

custom claimsも設定できるので便利。

クライアントからの呼び出し

node.jsから呼び出しを行う。

firebaseをinitializeAppした後、それぞれuseEmulator()をしてあげれば良い。
functionのregionも通常通り指定でOK。

const firebase = require("firebase")

  const firebaseConfig = {
    apiKey: "xxxxxxxxxxxx",
    authDomain: "test.service.local",
    databaseURL: "xxxxxxxxxxx",
    projectId: "test-service",
    storageBucket: "test-service.appspot.com",
    messagingSenderId: "000000000",
    appId: "xxxxxxxxxxxxxxxxxxxxx"
  };

firebase.initializeApp(firebaseConfig);

let auth = firebase.default.auth();
let functions = firebase.default.app().functions("asia-northeast1");
let db = firebase.default.firestore();

//emulator設定
auth.useEmulator("http://localhost:9099");
functions.useEmulator("localhost", 5001);
db.useEmulator("localhost", 8080);


(async () => {

  try {

    //auth emulatorへのアクセス(ログイン)
    await auth.signInWithEmailAndPassword("[email protected]", "password");

    //firestore emulatorへのアクセス
    const snapshot = await db.collection("test").get();
    snapshot.docs.map(doc => console.log(doc.data().name));

    //function emulatorへのアクセス
    const func = await functions.httpsCallable("testFunction")({});
    console.log(func.data);

  } catch (e) {
    console.log(e);
  }

})();


本番のfirestoreデータをemulator用に利用する

本番のfirestoreに既にデータが入っていてそれをエミュレータ上で利用したい場合がある。
そんな時はデータを予め本番環境からエクスポートしておく必要がある。
手順が若干面倒なのでこれも念の為メモ。

firestoreのエクスポート

firestoreデータのエクスポートは以下のGCPコンソールから実行できる。
必要なコレクションのみチェックしてエクスポートしておく

ローカルディスクへのダウンロード

エクスポートはstorage上にしか保存できいないため、さらにそれをローカルディスクに保存するにはgsutilツールを利用しなければならない。
以下を予めインストールしておく

* gsutilのインストール
https://cloud.google.com/storage/docs/gsutil_install?hl=ja

以下のコマンドを実行してダウンロードする

$ gsutil -m cp -r gs://<エクスポート先のstorageアドレス> <保存先のパス>

コピーしたデータを利用してemulatorを開始する

ローカルディスクに保存したデータをfirestoreのデータとして読み込んで起動するには、--import オプションを使用する

以下のようにコピーしたデータへのパスをオプション引数に渡して実行する。この時、パスは「xxxx.overall_export_metadata」がルートとなるように指定する。

$ firebase emulators:start --only firestore --import=<ダウンロード保存したディレクトリへのパス>

firestore emulatorの画面を見るとデータがインポートされていることが確認できる

emulator上で追加したデータをエクスポート

emulatorを使ってデータを追加した場合、emulatorを終了すると基本全てクリアされる。
そのためauthなどを使うテストの場合いちいち再作成しなければならない。
その場合、終了時に追加したデータをエクスポートするオプション--export-on-exitをつけると良い。

$ firebase emulators:start --export-on-exit=<エクスポート先>