FirestoreのエミュレータをCI環境下でキャッシュするための方法や、ローカル環境でも無駄なエミュレータのインストールを走らせるのを抑制するための方法を書いてみます。

エミュレータの保存場所

以下のコマンドでダウンロードしたエミュレータのファイルは、~/.cache/firebase/emulators/ 以下に保存されます。

$ firebase setup:emulators:firestore
# Realtime Databaseの場合
$ firebase setup:emulators:database

$ ls ~/.cache/firebase/emulators
cloud-firestore-emulator-v1.9.0.jar*
firebase-database-emulator-v4.2.0.jar*

ファイル名としては cloud-firestore-emulator-v{version}.jar といった規則になっています。
エミュレータのバージョン自体は firebase-tools のバージョン毎に使用されるバージョンが決まるようになっています。
firebase-tools のバージョンを上げた場合は再度インストールする必要がでてきます。

各種CI(サービス)では、 ~/.cache/firebase/emulators/ 以下にあるエミュレータをキャッシュ/リストアできるように書いてあげれば良いかなと思います。

エミュレータがインストールされているかを調べる

Shell Script上でエミュレータがインストール済みかを調べるには以下のような形で書いてあげれば判別が可能です。

if ls ~/.cache/firebase/emulators/cloud-firestore-emulator-v*.jar 1> /dev/null 2>&1; then
  echo 'emulators already installed.'
else
  firebase setup:emulators:firestore
fi

ただ、これでは firebase-tools のバージョンを上げた場合、任意のバージョンのエミュレータが存在していることになってsetupを走らせることができないので、バージョン指定で判定するのも一つの手です

VERSION=1.8.4
if [[ -e ~/.cache/firebase/emulators/cloud-firestore-emulator-v$VERSION.jar ]]; then
  echo 'emulators already installed.'
else
  firebase setup:emulators:firestore
fi

この場合は、VERSIONの指定を、firebase-toolsの更新に合わせて変えて上げる必要が出てきます。


いずれにしても、firebase-tools自体そこまで頻繁にアップデートしないのであればどちらで判定しても大差はないかなと思います。

何故キャッシュしたりインストール済か判別したほうが良いのか

$ firebase setup:emulators:firestore
$ firebase emulators:exec './test.sh' --only firestore --debug

といった具合で実行前に都度都度エミュレータをダウンロードするのも悪くはないのですが、Firestoreのエミュレータに関しては 60MB ほど容量があるので、できればキャッシュしたり、事前にインストール済かをチェックしてあげるほうが、CIの実行時間にも通信量にも優しいかなと思います。