Firebaseエミュレータの使い方を実例で解説(起動・停止・データ保存・仮想コンソールへのアクセス方法)

firebase-prograshi(プロぐらし)-kv Firebase
記事内に広告が含まれていることがあります。

「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
Point

既に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
Point

.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」です。

タイトルとURLをコピーしました