NodejsアプリのホスティングにFirebaseを選んだ話

Firebaseというのが良く分かっていなかったですが、前回のエントリでGoogle Cloud Fuctionsを使った勢いで新規作成してみました。

やったのは以下サイトと同じ手順ですが、勉強の意味も込めてこのエントリで写経します。

[Node.js によるアプリを Firebase で Hosting する最短の道 - Qiita](https://qiita.com/Satachito/items/c175645644af759cc71c)

まずはnodejs用のfirebaseツールをインストール

```cmd
C:\>npm install -g firebase-tools
```

firebaseツールより、Google Cloud Functions上のfirebaseにログイン。コマンド実行後、GUIでのログイン画面が出るのでID/Passwordを入力

```cmd
C:>\firebase login
? Allow Firebase to collect anonymous CLI usage and error reporting information? Yes
```

ローカル上にfirebaseのプロジェクトを作成。firebase initを実行後、各種コマンドに答えていきます。ちなみにこの時、クラウド上のfirebaseプロジェクトを指定させられるので、事前に作成しておくのが良いです。ここでは"myfirstfirebaseproject-a6cdc"を指定しています。

```cmd
C:\first_firebase>firebase init

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

  C:\first_firebase

? Are you ready to proceed? Yes
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. Functions: Configure and deploy Cloud Functions, Hosting: Configure and deploy Firebase Hosting sites

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

? Select a default Firebase project for this directory: myfirstfirebaseproject-a6cdc (MyFirstFirebaseProject)
i  Using project myfirstfirebaseproject-a6cdc (MyFirstFirebaseProject)

=== Functions Setup

A functions directory will be created in your project with a Node.js
package pre-configured. Functions can be deployed with firebase deploy.

? What language would you like to use to write Cloud Functions? JavaScript
? Do you want to use ESLint to catch probable bugs and enforce style? No
+  Wrote functions/package.json
+  Wrote functions/index.js
+  Wrote functions/.gitignore
? Do you want to install dependencies with npm now? Yes

> protobufjs@6.8.8 postinstall C:\first_firebase\functions\node_modules\protobufjs
> node scripts/postinstall

npm notice created a lockfile as package-lock.json. You should commit this file.
added 249 packages from 199 contributors and audited 700 packages in 75.543s
found 0 vulnerabilities


=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No
+  Wrote public/404.html
+  Wrote public/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...
i  Writing gitignore file to .gitignore...

+  Firebase initialization complete!
```
デプロイすれば、Web上にプロジェクトが反映されます。

- 静的コンテンツは　https://＜Firebase のプロジェクト名＞.firebaseapp.com
- 動的コンテンツは　https://us-central1-＜Firebase のプロジェクト名＞.cloudfunctions.net/helloWorld

で確認可能です。

静的コンテンツは、ローカル上のpublic/index.htmlの内容が、動的コンテンツは、ローカル上のfunctions/index.jsの内容が表示されます。デフォルトではindex.jsの内容は全てコメントアウトされているので、コメントアウトを解除してからデプロイして表示確認を行います。

```cmd
C:\first_firebase>firebase deploy

=== Deploying to 'myfirstfirebaseproject-a6cdc'...

i  deploying functions, hosting
i  functions: ensuring necessary APIs are enabled...
+  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (25.67 KB) for uploading
+  functions: functions folder uploaded successfully
i  hosting[myfirstfirebaseproject-a6cdc]: beginning deploy...
i  hosting[myfirstfirebaseproject-a6cdc]: found 2 files in public
+  hosting[myfirstfirebaseproject-a6cdc]: file upload complete
i  functions: creating Node.js 8 function helloWorld(us-central1)...
+  functions[helloWorld(us-central1)]: Successful create operation.
Function URL (helloWorld): https://us-central1-myfirstfirebaseproject-a6cdc.cloudfunctions.net/helloWorld
i  hosting[myfirstfirebaseproject-a6cdc]: finalizing version...
+  hosting[myfirstfirebaseproject-a6cdc]: version finalized
i  hosting[myfirstfirebaseproject-a6cdc]: releasing new version...
+  hosting[myfirstfirebaseproject-a6cdc]: release complete

+  Deploy complete!

Project Console: https://console.firebase.google.com/project/myfirstfirebaseproject-a6cdc/overview
Hosting URL: https://myfirstfirebaseproject-a6cdc.firebaseapp.com
```

デプロイの前にローカルで確認する場合、firebaseに含まれているサーバーを起動し、ローカル上から確認できます。

- 静的コンテンツは http://localhost:5000
- 動的コンテンツは http://localhost:5001/＜Firebase のプロジェクト名＞/us-central1/helloWorld


```cmd
C:\first_firebase>firebase serve

=== Serving from 'C:\first_firebase'...

+  functions: Using node@8 from host.
i  hosting: Serving hosting files from: public
+  hosting: Local server: http://localhost:5000
127.0.0.1 - - [15/Jul/2019:07:03:39 +0000] "GET / HTTP/1.1" 200 3505 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
+  functions: Emulator started at http://localhost:5001
i  functions: Watching "C:\first_firebase\functions" for Cloud Functions...
127.0.0.1 - - [15/Jul/2019:07:03:39 +0000] "GET /__/firebase/init.js HTTP/1.1" 200 - "http://localhost:5000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
i  functions: HTTP trigger initialized at http://localhost:5001/myfirstfirebaseproject-a6cdc/us-central1/helloWorld
>  (node:8936) ExperimentalWarning: The http2 module is an experimental API.
i  functions: Beginning execution of "helloWorld"
```

## 感想

GUIからぽちぽち、CUIからぽちぽちでデプロイまで出来てしまったので「勉強した感」は少ないですが、手軽にWebサービスの公開まで出来て楽だと思いました。

特にfirebase serveでローカルでのデバックが出来るのが楽だな、と思いました。他のWebApp系のPaaSもそうかもしれませんが、firebaseはバックエンド系のサービスが全て1つにまとまっているパッケージなので、他のWebAppsやらdatabaseを組み合わせた運用の場合よりもハマりどころが少なくて楽そうかも、と期待しています。

## 余談

今後の勉強プランです。

私の最終目的は「かっちょいいWebサービスを作りたい」であり、firebaseやらのバックエンドの勉強やプログラミングの勉強は目的ではありません。よって、最短ルールで「かっちょいいWebサービスを作る」道を進みたく、そのための技術勉強です。ちなみに「かっちょいいWebサービス」のためにデザインには凝りたいですが、1からデザインを組む技術もないので、何らかのフレームワーク、例えばVue.jsに頼ろうと思っています。

さて、Vue.jsを使うためにHTML/CSS/JavaScriptを基礎から勉強するぞ！とやっていると、Vue.jsまでたどり着くのに何か月かかるんだ、となってしまいやる気がなくなってしまいます。よって勉強は**目的に近い部分からやり始めます。**つまり、Vue.jsをいきなりfirebase上で動かすことを最初の目標とします。

とはいえ私もエンジニア、コピペで動いたとしても仕組みが知りたくなってくる。よって最初の目標を達成した後は、Vue.jsを支える技術であるnode.jsの勉強をして理解を深めます。その後、Vue.jsに戻って(おそらくコピペで実装した箇所の理解が深まっているはずなので)自分の手でカスタマイズして勉強。その後、node.jsを支える技術であるJavaScriptの勉強…と、**技術レイヤを掘っていきつつ、目的に近い部分に反映させていくやり方で勉強を進めます。**

- vue.jsのチュートリアル
- firebase + vue.jsで触ってみる
- node.jsのチュートリアル
- これを理解した上でfirebase + vue.js + node.jsで触ってみる
- JavaScriptのチュートリアル
- これを理解した上でfirebase + vue.js + node.js + JavaScriptで触ってみる