「Firebaseの本番環境を触るのが怖い」「テストデータを汚したくない」と感じていませんか?そんな悩みを解決するのが、ローカルPC上に擬似的なFirebase環境を構築できる「Firebaseエミュレーター」です。
本記事では、Firebaseエミュレーターの導入手順をステップバイステップで解説しています。
基本の起動・停止コマンドはもちろん、開発効率を劇的に上げる「データの保存・復元方法」や、ブラウザで直感的にデータを操作できる「Emulator UI(仮想コンソール)」へのアクセス方法まで、実例を交えて詳しく紹介しています。
この記事を読めば、本番環境を一切汚さずに、安全かつ高速に開発を進めるスキルが身につきます。
Firebaseエミュレーターとは何か?
Firebase エミュレーターは、クラウド上の本番環境とは別に、自分の PC 内で仮想のFirebase環境を作ることができる強力なツールです。
Firebaseエミュレーターとは何かの詳細については下記をご参考ください。
Firebaseエミュレータの実行に必要なもの
Firebaseエミュレーターを動かすには以下が必要です。
- Firebaseアカウント/プロジェクト
- Firebaseを使ったアプリケーション
- JAVA(JDK)
- Firebase CLI
Firebaseを使ったアプリの作成方法
Firebaseを使ったアプリの作成方法は下記をご参考ください。
Firebase CLIの導入方法
Firebase CLIの導入方法は下記をご参考ください。
JAVA(SDK)のインストール方法
JAVA(SDK)のインストール方法は以下をご参考ください。
【実例】Firebaseエミュレーターを使う方法
Firebaseエミュレーターを使いたいプロジェクトディレクトリに移動します。
【手順1】エミュレーターのインストール
firebaseの設定をします。
firebase init既にfirebase initを実行したことがあっても、再度実行して問題ありません。既存のデータは上書きや削除されずに残ります。
Emulatorsにチェックを入れます。

既存サービスのポートを選びます。基本的にはデフォルトで問題ありません。

Emulator UI を有効にするか聞かれるので Yes を選択します。

エミュレーターをダウンロードします。

「Firebase initialization complete!」と表示されれば、エミュレーターのインストールは完了です。
Firebase CLIの設定ファイル firebase.json が以下のようになります。
{
"firestore": {
"database": "(default)",
"location": "asia-northeast1",
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"emulators": {
"firestore": {
"port": 8080
},
"ui": {
"enabled": true
},
"singleProjectMode": true
}
}
【手順2】firebase.tsにエミュレーターを見に行く処理を追記する
現状だとエミュレーターを起動しても、アプリはエミュレーターを無視してクラウド上のFirebaseを見に行ってしまいます。
なお、開発中もFirebaseのエミュレーターとクラウド上の環境への接続を切り替えられるように、.env.localの環境変数で管理すると便利です。
.env.localに以下を追記します。
#Firebaseエミュレーターを使わない場合はfalseにする
NEXT_PUBLIC_USE_FIREBASE_EMULATOR=true.env.localで管理すると本番公開時に安全です。
.env.local ファイルはアップロードされません。そのため、本番で勝手に true になることがなく、確実にクラウドのFirebaseに繋がります。
Firebaseを自動化しているファイル(firebase.js / firebase.ts)で initializeAppを行っているファイルに①エミュレーターのインポートと②条件分岐を追記します。
import { initializeApp } from "firebase/app";
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore"; //connectFirestoreEmulatorを追加
import { getAuth, connectAuthEmulator } from "firebase/auth"; //connectAuthEmulatorを追加
import { getFunctions, connectFunctionsEmulator } from "firebase/functions"; //connectFunctionsEmulatorを追加
import { getStorage, connectStorageEmulator } from "firebase/storage"; //connectStorageEmulatorを追加// localhostの場合、接続先をエミュレーターに切り替える
if (process.env.NEXT_PUBLIC_USE_FIREBASE_EMULATOR === 'true' && process.env.NODE_ENV === 'development') {
connectFirestoreEmulator(db, "localhost", 8080);
connectAuthEmulator(auth, "http://localhost:9099");
connectFunctionsEmulator(functions, "localhost", 5001);
connectStorageEmulator(storage, "localhost", 9199);
}作成していないインスタンス(使わないサービス)はコメントアウトしてください。
全体像の例は以下のようになります。
import { initializeApp, getApps } from "firebase/app";
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore"; //connectFirestoreEmulatorを追加
import { getAuth, connectAuthEmulator } from "firebase/auth"; //connectAuthEmulatorを追加
// import { getFunctions, connectFunctionsEmulator } from "firebase/functions"; //connectFunctionsEmulatorを追加
// import { getStorage, connectStorageEmulator } from "firebase/storage"; //connectStorageEmulatorを追加
//process.envで環境変数を読み込む
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};
//各サービスのインスタンスを作成
//// Next.jsは開発中に何度もリロードされるため、二重初期化を防ぐこの書き方が推奨されます
const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
const db = getFirestore(app);
const auth = getAuth(app);
// 開発環境の場合、接続先をエミュレーターに切り替える(本番につなぎたい場合は.env.localの変数をfalseにする)
if (process.env.NEXT_PUBLIC_USE_FIREBASE_EMULATOR === 'true' && process.env.NODE_ENV === 'development') {
connectFirestoreEmulator(db, "localhost", 8080);
connectAuthEmulator(auth, "http://localhost:9099");
// connectFunctionsEmulator(functions, "localhost", 5001);
// connectStorageEmulator(storage, "localhost", 9199);
}
export { app, db, auth };(補足)if文の書き方の注意点
エミュレーターの接続条件を記述する際のif文の書き方がいくつかあります。
.env.localでどのFirebaseに接続するか切り替える
if (process.env.NEXT_PUBLIC_USE_FIREBASE_EMULATOR === 'true' && process.env.NODE_ENV === 'development') {・・・}.env.localの環境変数「NEXT_PUBLIC_USE_FIREBASE_EMULATOR」の値を見に行きます。
「開発環境だけどクラウド上のFirebaseに接続してテストしたい」と言う場合に、.env.localの環境変数をfalseにするだけで対応できます。
npm run devで常にエミュレーターにつながってしまう
if (process.env.NODE_ENV === 'development') {・・・}この場合、npm run devを実行したときに、必ずエミュレーターにつながってしまいます。
開発環境でクラウド上のFirebaseをテストしたいときに不便です。
(NG)サーバー側のコード実行でエラーが出る
if (location.hostname === "localhost") {・・・}上記の場合、ブラウザで動くときは問題ありませんが、サーバー側(SSR)でコードが実行された瞬間に「locationという変数がない」というエラーが出てアプリが止まってしまうことがあります。
(非推奨)サーバー側の処理がFirebaseエミュレーターにつながらない
if (typeof window !== "undefined" && window.location.hostname === "localhost") {・・・}typeof window !== “undefined” を追加することで、ブラウザ環境以外、すなわちサーバーでの処理はエミュレーターを使わない設定になります。
ただし、Admin SDKなどサーバー側で使うFirebaseのサービスを使う場合にエミュレーターに接続されなくなります。
【手順3】エミュレーターを起動する
エミュレーターを起動するには、以下のコマンドを実行します。
firebase emulators:start
データを保持したい場合は以下のようオプションをつけて起動します。
firebase emulators:start --import=./saved-data --export-on-exitこれで、Firebaseエミュレーターが起動します。

以上でエミュレーターの起動は完了です。
エミュレーターの停止
エミュレーターを停止するには、「ctrl + c」をするだけです。
これでPCのメモリも開放されます。
エミュレータのコンソール
Firebaseエミュレータを起動すると、コンソールも起動します。
デフォルトでは、http://127.0.0.1:4000/ です。

クラウド上のFirebaseと同じく、各サービスにアクセスし、手動でデータの追加や編集をすることもできます。

別コンソールで「npm run dev」を実行し、ブラウザからデータを保存したところ、きちんとFirestoreのエミュレーターにデータが保存されました。

↓ エミュレーターのFirestoreコンソールを確認

なおブラウザの下部にはFirebaseエミュレーターを使っていることが表示されています。

保存を有効にしている場合
エミュレーター起動時に保存を有効にしている場合は、エミュレーターを終了したときに指定したフォルダが自動生成されます。
既に存在する場合は、新しいデータで上書きされます。

エミュレーターのターミナルは「java」
Firebaseエミュレーター起動時のターミナルは「java」になります。
npm run devで起動したフロントエンドのアプリは「node」です。




