忘備録の趣旨
僕は普段、仕事のプロジェクトではReact NativeとFirebaseを使って開発を行っています。
React NativeとFirebaseを使って開発を行うときは、FirebaseのエミュレーターであるFirebase Local EmulatorSuiteを使って開発を行います。
この記事では、どのようにローカルでエミュレータを起動しているかと、どのようにアプリからエミュレータに接続するのかを、将来の自分のためにまとめようと思います。
Firebase Local EmulatorSuiteを起動する手順
まずは、プロジェクトをビルドします。
yarn build
GOOGLE_APPLICATION_CREDENTIALS
環境変数に、サービスアカウントファイルのパスを指定しながら、firebase emulators:start
コマンドを実行してエミュレータを起動します。
GOOGLE_APPLICATION_CREDENTIALS='./path/to/serviceAccountKey.json' firebase emulators:start
ポートが開いていないためエミュレーターが起動できない場合の解決方法
起動中のエミュレーターを正常に終了できなかった後に、再度エミュレーターを上記の手順で起動しようとすると次のようなエラーが発生することがあります。
i emulators: Starting emulators: auth, functions, firestore, database, hosting, pubsub, storage
⚠ firestore: Port 8080 is not open on localhost (127.0.0.1,::1), could not start Firestore Emulator.
⚠ firestore: To select a different host/port, specify that host/port in a firebase.json config file:
これは、Port 8080が開いていないため、Firestoreエミュレーターを起動できないということを表しています。
これを解決するためには、kill
コマンドを使用して、ポート番号8080を使用中のプロセスを強制的に終了させる必要があります。
ポート番号8080(Firestore Emulator)で問題が起きている場合は次のコマンドを実行します。
kill -9 $(lsof -t -i:8080)
ポート番号8085(Pub/Sub Emulator)で問題が起きている場合は次のコマンドを実行します。
kill -9 $(lsof -t -i:8085)
ポート番号9000(Database Emulator)で問題が起きている場合は次のコマンドを実行します。
kill -9 $(lsof -t -i:9000)
React Nativeからエミュレータに接続する方法
最初にinitializeApp()
を呼び出して、FirebaseApp
のインスタンスを取得します。
const firebase = initializeApp({
projectId: "project-id",
apiKey: "api-key",
authDomain: "auth-domein",
storageBucket: "storage-bucket"
});
Auth Emulatorに接続する場合は次のようにします。
const auth = getAuth(firebase);
if (isAndroid) {
connectAuthEmulator(auth, "http://10.0.x.x:9099");
} else {
connectAuthEmulator(auth, "http://localhost:9099");
}
Firestore Emulatorに接続する場合は次のようにします。
const firestore = getFirestore(firebase);
if (isAndroid) {
connectFirestoreEmulator(firestore, "10.0.x.x", 8080)
} else {
connectFirestoreEmulator(firestore, "localhost", 8080)
}
Functions Emulatorに接続する場合は次のようにします。
export const functions = getFunctions(firebase, REGION);
if (isAndroid) {
connectFunctionsEmulator(functions, "10.0.x.x", 5001);
} else {
connectFunctionsEmulator(functions, "localhost", 5001);
}
あとは、以下のコマンドを実行して、React Native(Expo)アプリを起動するだけです。
expo start --clear
Androidの時だけ"localhost"ではなくIPアドレスを指定する理由
上記のコードでは、Androidエミュレーターで実行している時にだけ直接IPアドレスを渡してエミュレーターに接続する関数を呼び出しています。
これは、Androidのエミュレーター環境では、"localhost"が解決しないことが多々ありエミュレーターに接続できないという問題が僕の環境ではよく発生していました。
そのため、その問題を解決するために直接IPアドレスを指定しています。
IPアドレスを確認する方法(Mac編)
開発環境のIPアドレスを確認する方法を紹介します。今回はMacでの場合のみ紹介させていただきます。あらかじめご了承ください。
設定アプリを開いて、左のサイドメニューからネットワークを選択します。
Wi-Fiをクリックします。
接続されているWi-Fiの詳細ボタンをクリックします。
このIPアドレスと表示されているが、エミュレーターに接続する際に使用可能なIPアドレスです。
まとめ
Firebase Local EmulatorSuiteを起動をするときに、何度も手打ちしたりコピペしたりするのは大変だと思うので、package.json
のscripts
にスクリプトとして登録しておくことをお勧めします。
"scripts": {
"start:emulators": "yarn build && GOOGLE_APPLICATION_CREDENTIALS='./path/to/secretKey.json' firebase emulators:start",
...
}