この記事の内容
- FirebaseでReactのSPAを作る際の開発環境構築手順を紹介します
- CORS等のはまりどころ回避方法を解説します
- create-react-appはちょっと触ったことがあるぐらいが想定です
- Firebase自体の概要はここに書きました
開発環境整備手順
以下の手順はWindows10, VScode, WSLの環境で確認しています
準備
- 使うツールをインストールします
npm install -g create-react-app
npm install -g firebase-tools
-
firebase-tools
はfirebase管理用のコマンドラインツールです -
create-react-app
で初期化します```bash create-react-app gallery-tech ```
- gallery-tech というディレクトリが作られ、その中がreact用に初期化されでいます
- ところどころで出てくるgallery-techは私がこれから作るアプリ名なのでスルーしてください
-
- 「Firebase 向け Google アナリティクスのデータ共有にデフォルトの設定を使用する」はオフでもいいのですが、今回はオンにします
-
firebaseの初期化
これで初期化完了です
動作確認
-
npm run start
を実行し、reactのローカルデバッグ起動(webpack dev server)を試す
- ブラウザが起動してこのような画面が出れば成功です。
- 試しに
src/App.js
のEdit <code>src/App.js</code> and save to reload.
あたりを編集・保存すると、リアルタイムでブラウザの内容も変わっているのが確認できます
-
npm run build
を実行し、コンパイルしてみます。 -
firebase serve
を実行し、firebaseのローカルデバッグサーバーを起動する
-
firebase functionsの動作確認をするため、
functions/index.js
を編集します。 -
- functions, hostingのデバッグ用ローカルサーバーが起動します
- コマンドの結果に出ているURLにアクセスすると結果が表示されます。
- 補足事項
-
firebase serve
の結果で出てくるhttp://localhost:5000/
はbuild
ディレクトリを見ています。ソースコードを編集してもビルドするまでは反映されません - ローカルのNodejsのバージョンがfirebaseでサポートされてないバージョンだと警告が出ます。きっちりしたい人はfirebaseにそろえるといいと思いますが、今回は面倒なのでそのままにします。
- firestoreの方は残念ながらローカルのデバッグサーバーがないようです。
- まだセキュリティルールを試せるローカルエミュレータがある程度です
-
- 終わったらCtr-Cで
firebase serve
やnpm run start
を終了させます
サーバーへデプロイ
-
firebase deploy
を実行します。完了すると次のような表示が出ます。
- 実際にURLにアクセスするとアプリがデプロイされているのが確認できます
- functionsは
https://us-central1-gallery-tech.cloudfunctions.net/helloWorld
- hostingは
https://gallery-tech.firebaseapp.com/
- functionsは
- 実際にURLにアクセスするとアプリがデプロイされているのが確認できます
まだいろいろ足りていません。
functionsのFQDNとHostingのFQDNが異なるため、CORSで失敗します
-
fetch("https://us-central1-gallery-tech.cloudfunctions.net/helloWorld")
を実行した例
- functions側でCORS許可する方法もありますが、今回はHostingのリライトを使用します
...
"rewrites": [
{
"source": "/api/**",
"function": "api"
},
{
"source": "**",
"function": "/index.html"
}
]
exports.api = functions.https.onRequest((request, response) => {
response.send(request.path);
});
-
hostingのFQDNに対し、
/api/
のパスでアクセスしてきたものはfunctionsのapi関数の結果を返すようにします-
/api/
配下のパスが何であっても、呼び出されるfunctionsの関数はapi関数です
-
-
functions側では、
request.path
でどのようなパスでアクセスしてきたかを取得できます。- これを用いてapi関数の中で分岐を書けば、パスによって呼び出される関数を変えることができます
- 例えば、hostingに
/api/helloWorld
でアクセスした場合、functionsのrequest.path
は/api/helloWorld
です
-
これで、クライアント側のjavascriptで
fetch("/api/helloWorld")
とすればfunctionsのapi関数が呼び出せます- ブラウザから見ると同一オリジンになるため、CORSのエラーは起きません
webpack dev serverがローカルのfunctionsを呼び出せない
-
このままだと、ローカルデバッグでfunctionsとの連携がテストできません
- webpack dev serverは
http://localhost:3000/
で待ち受けています - firebaseのhostingは
http://localhost:5000
で待ち受けています。- 上で解説したfunctionsへのリライトをこのポートで行います
- webpack dev server側で開いたサイトの
fetch("/api/helloWorld")
というコードはhttp://localhost:3000/api/helloWorld
を呼び出すのでエラーになります
- webpack dev serverは
-
そのため、次のproxy設定がpackage.jsonに必要です。(紛らわしい名前ですが、よく企業にあるhttp proxyとは無関係の設定です)
{
...
"proxy": "http://localhost:5000",
"scripts": {
...
}
-
http://localhost:3000/
へのアクセスでファイルがない場合、http://localhost:5000
に飛ばしてくれます
firestoreのテストデータはどうするか
- ローカルで開発してるときに本番データにアクセスさせたくないですよね
- (個人開発なら別に気にしなくてもいいかもしれません)
- 現状はfirebaseのプロジェクト自体を分けるぐらいしかなさそうです
- そこで、アクセス先のfirestoreを開発(ローカル)と本番で切り替える仕組みが必要になります
functionsのアクセス先firestore切り替え
環境設定で切り替えます
-
functionsサーバー側の環境設定はfirebase cliで行います
- 確認コマンド
firebase functions:config:get
- 設定コマンド
firebase functions:config:set service.stage=production"
-
service.stage
にproduction
を指定します。変数は必ず.
が1つ必要です
-
- 確認コマンド
-
functionsのコード内からは
functions.config().service.stage
で値を取得できます -
ローカル実行のfunctionsサーバーの環境設定は
functions/.runtimeconfig.json
に書きます-
firebase functions:config:get > functions/.runtimeconfig.json
を実行して、できたファイルを編集します
-
-
上記の環境設定方法を使って、アクセス先firestoreのアクセス設定を切り替えてやればいいでしょう
hostingのアクセス先firestore切り替え
create-react-appの機能を使います。
- .envファイルと
process.env
で切り替えられます。npm run build
とnpm run start
の時で格納される値を変えられます - ここに解説があります
実際にアプリを書いていく解説は次回からします