FirebaseでWebアプリをデプロイする方法

今日はGoogleが開発・運営するFirebase上で、Hostingという機能を使って、ReactのWebアプリ又はWebサイトをデプロイする方法をご紹介します。FirebaseはGoogle Cloud Platform(GCP)上で動く多機能なWebサーバ(大部分が無料)で、他にもリアルタイムデータベース(Could Firestore)、認証機能(Firebase Authentication)、決済機能(Stripe)等のFirebaseアプリも備えています。他のサーバーでHostingをしつつ、firebaseが提供する機能を使うことも可能です(Authorized Domain登録は別途必要)。Firebaseのようなサービスは、BaaS(Backend-as-a-Service)と呼ばれることもあります。

FirebaseはもともとGoogleとは資本関係のないFirebase Inc.という会社が2011年に開発したものでしたが、2014年にGoogleが同社を買収してGoogleのサービスとなりました。

以下、HTM、CSS、JS、その他フロントエンドのJS付属パッケージ一式(React.js、Material UI、Chart.jsなど)で構成されるプロジェクトが、ローカルでは既に完成しているとして、具体的なデプロイの方法解説します(今回はFirebaseアプリは使いませんが、使う場合もデプロイの過程は同じです)。

なお、本稿の最終章「コンフィギュレーションファイル、firebase.jsの作成」の部分は、2022年4月に内容を書き換えました(firebaseのアップデートに対応)。また、本稿はReactを前提にしています。Next.jsについては、本稿4章の「Hosting Setup」を参考にしてください。

必要な環境又は事前準備

  • Node.js(npmコマンドを使うため)
  • デプロイするReactのWebサイト又はWebアプリが開発環境で完成済み

Firebaseのサイト上での初期設定

まずはFirebase上での設定を行います。gmailアカウントを作成し、Firebaseのホームページにアクセス、続いて、中央の「Get started」ではなく、右上の「Go to console」をクリックします。



gmailでのログインを求められるので、ログインします。


次に、プロジェクトの名称を半角英数字で入力し、下段の「続行」をクリックします。




次の画面もそのまま「続行」をクリックします。Webアプリやサイトの解析に欠かせないGoogleアナリティクスは、有効のままいきましょう。




Firebase側の最後の設定です。Googleアナリティクスのアカウントがある人は、同アカウントを選択し、持ってない人はここでアカウントを作った後、右下の「プロジェクトを作成」をクリックします。




「プロジェクトを作成」をクリックの後、プロジェクト作成中の画面に遷移しますがそのまま放っておいて、ローカルPC(プロジェクト)のターミナルに戻ります。Webサイト又はWebアプリをデプロイするだけであれば、プロジェクト作成が完了後にウィンドウを閉じても問題ありません。他方Firebaseのユーザー認証やデータベース機能をWebアプリに実装する場合には、この段階ですぐにデプロイすることはないと思いますので、後述「Firebaseプロジェクト内でのアプリの登録方法」に進んでください。


Firebaseにおけるプロジェクトとは

Firebaseにおけるプロジェクトはアプリの上位概念で、具体的なアプリはプロジェクトの内側に作成(登録)します。デプロイするだけならアプリの登録は不要ですが、前述のFirebase内のデータベース(Could Firestore)、認証機能(Firebase Authentication)等を使用するにはプロジェクトを作成するだけではなく、アプリの登録を要します。両者の関係はややわかりにくいのですが、Firebaseでのプロジェクト作成はGoogle Cloud Project上で場所を確保しているだけであり、Firebaseに固有の機能を使うには別途Firebase上での設定を要すると考えるとわかりやすいかもしれません(下記、イメージ図)。Firebaseでのアプリの登録方法はホスティングの説明の後、本稿の下段で簡単にご紹介します。

A Firebase project is the top-level entity for Firebase. In a project, you create Firebase apps by registering your iOS, Android, or web apps. After you register your apps with Firebase, you can add the Firebase SDKs for any number of Firebase products, like Analytics, Cloud Firestore, Performance Monitoring, or Remote Config.

Firebase公式ドキュメント:Firebase >Docs > Guides

ローカルPC側の初期設定

Firebaseのサイト上でプロジェクトの設定を終えたら、ローカル環境において、FirebaseのCLI(コマンドラインインターフェイス)をグローバルにインストールします(”-g”の部分がグローバルへのインストールを意味します)。ターミナルを立ち上げ、次の2行を実行します。1行目は”-g”なしでアプリを立ち上げる都度インストール、2行目はグローバルにインストールします。

npm install firebase
npm install -g firebase-tools

続いて、ターミナルからFirebaseにログインします(2回目以降の更新の場合はここから始めます)。

firebase login



次のような画面がブラウザに立上がればログイン成功です。Firebaseにログイン済みの場合は表示されず、しばらくするとターミナルに「Already logged in as your_account@gmail.com」と表示されます。your_accountの部分は皆様のアカウントです。



「Allow Firebase to collect CLI usage and error reporting information?」と聞かれるので、「Yes」とします。ここでは「No」と拒否としても先に進めそうな気がしますが、差し障りないと思いますので「Yes」とします。この質問は初回しか聞かれないので、この質問がない場合は次の「firebase init」に進みます。



Webアプリを作成しているディレクトリーにいることを改めて「ls」で確認し、「firebase init」と打ち、ローカルプロジェクト側でFirebaseの環境を整えます。

firebase init

下記のように大文字で「FIREBASE」と表示されていれば、ここまでは順調です。続いて、「Are you ready to proceed(Y/n)」と問われるので、キーボードで「y」を押します。ここで「n」を押すと止まります。




矢印キーで上下に移動できるので、Hostingにカーソルを合わせて、スペースで選択、括弧内に※印が表示されていることを確認し、Enterを押します。



Project Setup

続いての選択画面で、FireBase側でのプロジェクトの設定をします。今回は初めの手順で既にFireBaseでプロジュクトを作っているので、「Use an existing project」を選択し、Enterを押します。





次に、FireBase上で「Select a default Firebase project for this directory」と表示されるので、先ほどFirebase上で作成したプロジェクトを矢印キーで選択し、Enterを押します。以上の過程でログインエラーが生じた場合は、本稿の最終章「追記 – firebase initでログインエラーが出る場合」をご覧ください。



Hosting Setup

続いて「What do you want to use as a public directory?」と聞かれます。ここでは後述ビルド実行時にbuildフォルダに全てが集約されるので「build」と入力します。なお、Next.jsの場合はbuildフォルダにビルドの結果が出力されません。また、Next.jsは他にも追加の設定が必要です。詳細はこちらVercel / next.js公式の「with-firebase-hosting」を参照ください。また、stack over flowの「How to deploy next.js app on Firebase Hosting」にあるMonashaさんの回答及びbrc-ddさんの編集が背景を理解するために有用です。



「Configure as a single-page app(rewrite all urls to /index.html)」?と聞かれるので、SPA(Single Page Application)なら「y」、そうでないなら「N」と入力して、Enterを押します。Single Page Applicationとは、HTMLファイルがindex.htmlだけで構成されるWebアプリです。例えば、以前の記事でご紹介した私のブラックジャックはSPAです。Next.jsあるいはReact Routerで複数のページを設定している場合はSPAではないので「N」です。



「Set up automatic builds and deploy with GitHub?」の部分はNoを選択します。ここでYesを選択するとGitHubを通じたデプロイが可能となりますが、追加の設定を要します。



もしGitHubとの連携をした場合は、次のような画像が現れます。





次に「Set up the workflow to run a build script before every deploy?」と聞かれれば、「y」を、続いて「What script should be run before every deploy?」と聞かれればそのままEnterを押してください。また、「Set up automatic deployment to your site’s live channel when a PR is merged」ともし聞かれなければ、「N」を押します。GitHub連携の部分でNoを選択した場合は以上3つの質問は聞かれないと思いますので、そのまま進んで大丈夫です。



初期設定完了

ここまで来ると、「firebase initialization complete!」 と表示されます。この段階ではFirebase側の準備が整い、ローカル環境とFireBaseの接続も保たれています。続いていよいよWebアプリをデプロイのために、ローカル側でデプロイのためのビルドフォルダを作成します。「npm run build」と入力します。このコマンドにより、ローカルのプロジェクトでインストールされるも使わなかったライブラリーなど不要なものが全て整理されます。


npm run build


下記画面の下から2行目のように「The build folder is ready to be deployed」と表示されれば(Reactの場合)、無事にWebアプリをデプロイするためのbuildフォルダが完成しています。



また、プロジェクトフォルダ内にも実際にbuildという名のフォルダが作成されていることも確認できます。


buildフォルダが出来たら、いよいよデプロイです。「firebase deploy」と入力します。

デプロイ完了


下記下段のようにHosting URLが表示されればWebアプリのFirebase上でのデプロイ成功です。表示されているURLがWebアプリのデプロイされているURLですので、そのままCtrl + クリックとしてもいいですし、コピーしてブラウザ上で確認しても大丈夫です。



2回目以降の更新

以上が初回のデプロイの方法ですが、2回目のデプロイ(更新)の方法もご紹介します(3行)。まずターミナルからFirebaseにログインします。ログイン方法は先ほどと同様です。

firebase login

続いて、ビルドを実施します。

npm run build

ターミナルで「The build folder is ready to be deployed」と表示されたことを確認した後、次のコードでデプロイします。

firebase deploy

Firebaseプロジェクト内でのアプリの登録方法

以上でデプロイ(Hosting)は可能ですが、最後にプロジェクト内でFirebaseアプリを登録する方法をご紹介します。Firebaseにおけるプロジェクトとアプリの違いは前述の通りです。Firebaseのホームページに戻り、右上のGo to Consoleを押すと先ほど作成したプロジェクトが表示される画面に移りますので、同プロジェクトの部分をクリックします。



続いて、左上のプロジェクトの概要の右側に歯車アイコンをクリックし、「プロジェクトを設定」をクリックします。



プロジェクトの設定という画面が開くので、下段マイアプリの中にあるコード>アイコンをクリックします。



続くアプリの登録画面では、アプリ名を入力、「Firebase Hosting」も「設定します」にチェックし、「アプリを登録」をクリックします。



次の部分でscriptタグを張るよう要請されますが、ここではこの工程をスキップして「次へ」を押します(後からできます)。



次の画面ではCLIをインストールするよう求めれますが、この記事の冒頭でご紹介した通りで済んでいますので、ここでも何もせずに「次へ」をクリックします。



続く画面ではローカル環境でfirebaseのプロジェクトを構築する方法が簡単に書いてありますが、この工程は前述の通り詳しく解説をいたしましたので、「コンソールに進む」をクリックします。


コンフィギュレーションファイル、firebase.jsの作成

アプリが無事に立ち上がりましたので、構成とある部分をクリックして、apikeyなどの情報の書かれたJavaScriptのオブジェクトをコピーします。この構成情報(configuration)はFirebaseの機能をフロントエンドから使用するときに必要ですので、ローカル側のアプリを作成している階層にfirebase.js(またはfirebase.config.js)というファイルを作成します。

この構成情報を後から取得する場合には、本稿「Firebaseプロジェクト内でのアプリの登録方法」のセクションで上から2つ目の画面(画像)での操作と同様に、プロジェクトの概要の横にある歯車アイコンから「プロジェクトを設定」をクリックするとご覧になれます。

(2022年4月に内容を更新)下記コード例では1-3行目でfirebaseの関連ライブラリーをンストール、5行目以降で構成オブジェクトを作成の後、initializeAppでfirebaseオブジェクト作成しています(フロントエンドReactとバックエンドfirebaseがこの行で接続します)。続く行ではよく使うデータベースのfirestoreと、認証のauthのオブジェクトを作成していますが、実際にそれらアプリを使うにはFirebaseサイト内での追加の設定が必要です。認証については私のこちらの記事「React + Firebaseを使ったユーザー認証の実装方法」を、Firestoreについては私のこちらの記事「React + Firestore【入門から実装まで】」を参照ください。なお下記コード例のfirebaseConfigオブジェクト内の値は架空の値です。



firebase.js

import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";

const firebaseConfig = {
apiKey: "adfasfavnaAJFDKCnjkasjlkASJLFNKSA",
authDomain: "myapp-d92bc.firebaseapp.com",
projectId: "myapp-d92bc",
storageBucket: "myapp-d92bc.appspot.com",
messagingSenderId: "15645156456156",
appId: "1:15645156456156:web:1516532e652c5459f5f6b44",
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);

export { auth };
export default db;

getAuthの役目

getAuth()で得られるauthはログイン済みユーザーのauthではなく、ローカル(クライアント)のWebアプリ上のFirebase Authenticationが、Firebasesサーバーと接続するためのauthです。コンポーネントからAuthenticationに関わるFirebaseの関数を呼び出すときは、毎回引数としてこのauthを渡す必要があります。上記事例のようにコンフィギュレーションファイルでgetAuth()を呼び出してauthをexportする方法の他にも、公式ドキュメンテーションのようにコンフィギュレーションファイルでgetAuth()を呼び出さず、各コンポーネントで関数を呼び出す都度、getAuth()を呼び出す方法もあります。

initializeAppのバグ改善

2021年の後半から、下記のfirebaseが初期化済みか否かを確認する処理は不要となりました。web Version 8.0からweb Version 9.0へのアップグレードに伴いバグが改善されたものと思われます。


2021年以前の古いプロジェクトでは、const app = initializeApp(firebaseConfig);の部分で、既に初期化されている状態でリロードするとエラーになる可能性があります。そこでgetAppsをfirebase/appからインポートの上、次のようにすると改善します。getApps().lengthが偽の場合、すなわち、まだappが初期化されていない場合は初期化しconst apに格納します。反対にgetApps().lengthが真の場合、すなわち既にappが存在する場合は、同appを取得してconst appに格納します。この処理をせずともエラーにならず、反対にこの処理をするとエラーが出る場合があります。その場合はconst app = initializeApp(firebaseConfig)に戻します。

import { initializeApp, getApps } from "firebase/app";

// 途中の記載を省略(上記を参照)

const app = !getApps().length ? initializeApp(firebaseConfig) : getApps();

以上でFirebaseのプロジェクト内でのアプリの登録作業(初動)は完了す。データベースのfirestoreや、認証のauthの等のFirabaseの諸機能の具体的な使用方法は、前述の私の別の記事をご覧ください。今日も最後まで読んで頂きありがとうございました。

下記のyoutubeでは動画でデプロイの方法を解説しています。ただ、こちらの動画のfirebase.jsの内容は古いので、firebase.jsの部分は上記の通りとてください。



追記 – firebase initでログインエラーが出る場合

firebase initをし、ホスティングの途中で下記のようなエラーが出ることがあります。

Error: Failed to list Firebase projects. See firebase-debug.log for more info.

firebase-debug.logを見ると下記のような記載があります。

 FirebaseError: HTTP Error: 401, Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential.

これはなんらかの原因でFirebase CLIと紐づいた開発者のGoogleのアカウントがFirebaseでの認証に失敗している状態です。下記のコマンドをターミナルで打ち再認証をします。

firebase login --reauth --no-localhost

下記のような指示がターミナルに現れます。1のSession IDは後ほど確認のために使います。このターミナルを閉じなければコピーの必要はありません。2のURLをクリックします。IDの部分は伏せてあります。



サインイン画面が表示されるので、Firebaeのログインで使用しているGoogleのアカウント選択します。


続く画面ではAllowを押します。



次に下記のような画面が表示されます。このコマンドは既に冒頭で実施しているので、下段の「Yes I just run this command」を押します。


次の画面では中央にsession IDが表示されていると思うので、冒頭のターミナルに表示されたsession IDとの一致を確認の上、下段の「Yes, this is my session ID」をクリックします。


下記が最後の画面です。中央にAuthorization codeが表示されていると思うので(下記では黒塗り)、コピーします。



ターミナルに戻り、下段に表示されている「Enter authorization code:」の部分に先ほどコピーしたauthorization codeを貼り付け、Enterを押します。「Success! Logged in as your_account@gmail.com」 と表示されれば完了です。