Help us understand the problem. What is going on with this article?

FirebaseをStaging環境とかDebug環境とかRelease環境で切り替えをする(Webアプリ編)

More than 3 years have passed since last update.

この記事は Firebase Advent Calendar 2016 2日目です。

はじめに

先日、プライベートで"Last Activity"というWebサービスをFirebaseで開発&公開しました。その際に一番苦労した開発環境 / 検証環境 / 本番環境の切り替えについてまとめようと思います。

本記事はSPA(Single Page Application)などのWebアプリ開発を想定しています。
iOSでの開発であれば下記の記事が参考になるかと思います。
FirebaseをStaging環境とかDebug環境とかRelease環境で切り替えをする

Firebaseの開発環境(Develop/Debug)と本番環境(Release)

これは特に難しいところはありません。公式が提供するFirebase CLIを利用すればOKです。

コンソールにてfirebase serveを実行すれば、開発機上でコードを実行でき、ブラウザから http://localhost:5000/ へアクセスすれば動作を確認することができます。

そしてfirebase deployを実行すれば、本番環境へコードがプッシュされ、自動でデプロイされます。いや~、便利ですね!

Firebaseの検証環境(Staging)

基本的な考え方としては「Firebase Consoleにて検証環境として新しいプロジェクトを作成し、必要に応じてfirebase use --addで切り替える」となります。
詳細は公式ドキュメント(和訳)がありますので、そちらをご覧ください。
Firebase Hosting での複数環境へのデプロイ

課題

これで万事OK!…ではありません。実は上記公式ブログで紹介されている方法には一つ罠があります。
それは「Firebase Hosting だけ を使うなら上記でOKだが、Realtime Databaseを使っている場合それは本番環境の方を参照してしまう」点です。

開発の初期段階で以下のようなコードをFirebase Consoleから取得したことを思い出してください。

<script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: "abcdefghijklmnopqrstuvwxyz1234567890ABC",
    authDomain: "YOUR-PROJECT-NAME.firebaseapp.com",
    databaseURL: "https://YOUR-PROJECT-NAME.firebaseio.com",
    storageBucket: "YOUR-PROJECT-NAME.appspot.com",
    messagingSenderId: "999999999999"
  };
  firebase.initializeApp(config);
</script>

ここでdatabaseURLを定義しているため、これを書き換えない限り、たとえ検証環境にデプロイされたコードが実行されていたとしても本番環境のDatabaseを参照しにいくのは道理です。
同じ理由でおそらくStorageも同様です。※未検証

解決策

上記問題について公式で解決策を用意してほしいところですが、とりあえず今どうにかする必要があります。私はそれにwebpackを利用しました。

webpackの概要、インストール方法等については下記ページをご覧ください。
webpack で始めるイマドキのフロントエンド開発

さて、本題です。

firebase.js
// Initialize Firebase
module.exports = {
  apiKey: __FB_API_KEY__,
  authDomain: __FB_AUTH_DOMAIN__,
  databaseURL: __FB_DATABASE_URL__,
  storageBucket: __FB_STORAGE_BUCKET__,
  messagingSenderId: __FB_MESSAGING_SENDER_ID__
};

環境によって変化する設定値をパラメータ化します。

_entry.js
// Initialize Firebase
var fbConfig = require('firebase.js');
firebase.initializeApp(fbConfig);
webpack.config.js
var webpack = require("webpack")
const path = require("path")

if (process.env.ENV == "prod") {
  // 本番環境の設定値
  FB_API_KEY = "abcdefghijklmnopqrstuvwxyz1234567890ABC";
  FB_AUTH_DOMAIN = "YOUR-PROJECT-NAME.firebaseapp.com";
  FB_DATABASE_URL = "https://YOUR-PROJECT-NAME.firebaseio.com";
  FB_STORAGE_BUCKET = "YOUR-PROJECT-NAME.appspot.com";
  FB_MESSAGING_SENDER_ID = "999999999999";
} else {
  // 検証環境の設定値
  FB_API_KEY = "lmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN";
  FB_AUTH_DOMAIN = "YOUR-PROJECT-STAGING.firebaseapp.com";
  FB_DATABASE_URL = "https://YOUR-PROJECT-STAGING.firebaseio.com";
  FB_STORAGE_BUCKET = "YOUR-PROJECT-STAGING.appspot.com";
  FB_MESSAGING_SENDER_ID = "000000000000";
}

module.exports = {
    entry: path.join(__dirname, "src", "_entry.js"),
    output: {
      path: path.join(__dirname, "public", "js"),
      filename: "app.js"
    },
    plugins: [
        new webpack.DefinePlugin({
          __FB_API_KEY__: JSON.stringify(FB_API_KEY),
          __FB_AUTH_DOMAIN__: JSON.stringify(FB_AUTH_DOMAIN),
          __FB_DATABASE_URL__: JSON.stringify(FB_DATABASE_URL),
          __FB_STORAGE_BUCKET__: JSON.stringify(FB_STORAGE_BUCKET),
          __FB_MESSAGING_SENDER_ID__: JSON.stringify(FB_MESSAGING_SENDER_ID)
        })
    ]
}

環境変数によって設定値を切り替えます。この方法は下記ページを参考にさせてもらいました。
Webpackを使ってJSでも.envしたい

開発時

コードを修正したら動作確認前にwebpackでビルドします。webpack --watchで自動的にビルドしてくれるらしいのですが、自分の環境(Bash on Ubuntu on Windows)では一回ビルドしてコマンドが終了してしまいます。なぜでしょうね?

検証環境デプロイ

firebase use --addにて検証環境を"stag"という名前で設定しているとします。
その場合、firebase use stag; firebase deployで検証環境へデプロイできます。
webpack -pをその前に実行すればコードを最小化したうえでデプロイが可能です。

本番環境デプロイ

同様に本番環境を"prod"という名前で設定しておきます。
ENV=prod webpack -p; firebase use prod; firebase deployで本番環境用にビルドしたコードがデプロイできます。webpackコマンドに環境変数で"prod"を渡しているのがポイントです。

さらに楽をするために

毎回複数のコマンドを入力するのは面倒くさいし、ミスをする可能性もあります。
package.jsonにこんな感じで定義するとnpm run-script deploy, npm run-script deploy-prodで実行でき、さらにいい感じになります。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "deploy": "webpack -p; firebase use stag; firebase deploy",
    "deploy-prod": "ENV=prod webpack -p; firebase use prod; firebase deploy; firebase use stag; webpack"
  },

商用環境デプロイ後にstagへ切り戻しているところがポイントです。

最後に

"Last Activity"はあなたの活動記録を残すサービスです。
最後に洗車をした日、散髪した日など、手軽に記録して後で振り返りたいときはありませんか?35歳を越えるとそんなことはしょっちゅうだよ!(半ギレ
ということで喉から手が出るほど欲しかったサービスをようやく手に入れて自分は満足です。あるある!となった方はぜひ使ってみてください。<(_ _)>
img01.png

fullkawa
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした