19
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ぼっち(´・ω・`)Advent Calendar 2018

Day 16

Firebase+Reactの開発環境構築とはまりどころ解説

Last updated at Posted at 2018-12-17

この記事の内容

  • 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は私がこれから作るアプリ名なのでスルーしてください
  • firebaeにログインし、プロジェクト追加します
    image.png

    • 「Firebase 向け Google アナリティクスのデータ共有にデフォルトの設定を使用する」はオフでもいいのですが、今回はオンにします
  • firebaseの初期化

    • 初回の場合はfirebase loginでログインします

    • gallery-techディレクトリでfirebase init --project gallery-techを実行します
      image.png

    • スペースキーを押すと選択できます。今回はFirestore,Functions,Hostingを選択します
      image.png

    • エンターを押すと対話形式でいろいろ設定項目を聞いてきます。次の2つ以外は基本的にデフォルトでOKです

      • publicディレクトリを何処にするか?という問いはbuildディレクトリにします。
        image.png
        • 本番用にwebpackでコンパイルしたものはbuildディレクトリに配置されるためです。
        • create-react-appで作られたpublicディレクトリがあると思いますが、それは静的コンテンツ配置用です
          • コンパイルするとbuildにコピーされます
      • SPA用に設定するか、という問いもYesにします
        image.png
    • firestoreの有効化はブラウザで行います。firebaseのサイトに行きます

      • 左のメニューからDatabaseを選択します。Firestoreの画面が出るので「データベースの作成」をクリックします
        image.png

      • ロックモード(アクセス全拒否)かテストモード(アクセス全許可)のどちらにするか聞かれます。今回はロックモードにします。
        image.png

これで初期化完了です

動作確認

  1. npm run startを実行し、reactのローカルデバッグ起動(webpack dev server)を試す
  • ブラウザが起動してこのような画面が出れば成功です。            
    image.png
  • 試しにsrc/App.jsEdit <code>src/App.js</code> and save to reload.あたりを編集・保存すると、リアルタイムでブラウザの内容も変わっているのが確認できます
  1. npm run buildを実行し、コンパイルしてみます。
  2. firebase serveを実行し、firebaseのローカルデバッグサーバーを起動する
  • firebase functionsの動作確認をするため、functions/index.jsを編集します。

  • コメントにあるHelloWorldをそのまま使います。
    image.png

  • firebase serveを実行します
    image.png

    • functions, hostingのデバッグ用ローカルサーバーが起動します
    • コマンドの結果に出ているURLにアクセスすると結果が表示されます。
      • vscodeの機能で、ctrキーを押しながらURLをクリックすると、ブラウザで開いてくれます。
        image.png
        image.png
    • 補足事項
      • firebase serveの結果で出てくるhttp://localhost:5000/buildディレクトリを見ています。ソースコードを編集してもビルドするまでは反映されません
      • ローカルのNodejsのバージョンがfirebaseでサポートされてないバージョンだと警告が出ます。きっちりしたい人はfirebaseにそろえるといいと思いますが、今回は面倒なのでそのままにします。
      • firestoreの方は残念ながらローカルのデバッグサーバーがないようです。
        • まだセキュリティルールを試せるローカルエミュレータがある程度です
  1. 終わったらCtr-Cでfirebase servenpm run startを終了させます

サーバーへデプロイ

  • firebase deployを実行します。完了すると次のような表示が出ます。
    image.png

    • 実際にURLにアクセスするとアプリがデプロイされているのが確認できます
      • functionsはhttps://us-central1-gallery-tech.cloudfunctions.net/helloWorld
      • hostingはhttps://gallery-tech.firebaseapp.com/

まだいろいろ足りていません。

functionsのFQDNとHostingのFQDNが異なるため、CORSで失敗します

  • fetch("https://us-central1-gallery-tech.cloudfunctions.net/helloWorld")を実行した例
    image.png
  • functions側でCORS許可する方法もありますが、今回はHostingのリライトを使用します
firebase.json
...
"rewrites": [
      {
        "source": "/api/**",
        "function": "api"
      },
      {
        "source": "**",
        "function": "/index.html"
      }
    ]
functions/index.js
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を呼び出すのでエラーになります
  • そのため、次のproxy設定がpackage.jsonに必要です。(紛らわしい名前ですが、よく企業にあるhttp proxyとは無関係の設定です)

package.json
{
  ...
  "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.stageproductionを指定します。変数は必ず.が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 buildnpm run startの時で格納される値を変えられます
  • ここに解説があります

実際にアプリを書いていく解説は次回からします

19
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?