Express-generatorでFirebase Functions+hostingを使ってWebアプリを作る

##試した環境
- MacOS:10.14.2(Mojave)
- node:v10.10.0
- npm:6.8.0
- express:4.16.0
- firebase:6.4.0
- firebase tools:7.0.2

##修正履歴
- 2019.8.3 firebase tools7.2.2ではpublicがなくなり、firebase-functions-testをインストールしろとの警告がなくなったので、削除
- 2019.9.30 firebase tools7.4.0ではpublicが復活、firebase-functions-testをインストールしろとの警告が再度表示されるようになったので、記載を復活
- 2019.10.26 firebase tools7.6.1では、firebase-functions-testをインストールしろとの警告がなくなったので、削除
- 2020.4.19 package.jsonのコピペする箇所がわかりにくいので、該当箇所を示すように修正
- 2020.5.2 node8が使えるようになったため、enginesを追加するように修正

##手順
0.firebase toolsをインストールしておく

```

$ npm install -g firebase-tools
```

1.適当なディレクトリを作成し、firebase initしてfirebaseプロジェクトを作成

```

$ firebase init
```
2.スペースバーでfunctionsとhostingを選択し、Enter
3.Select a default Firebase project for this directoryで、Firebaseプロジェクトを選択し、そのあとの質問は全てEnter
4.一旦、以下のコマンドでローカルサーバを起動

```
$ firebase serve --only functions,hosting
```

5.localhost:5000にアクセスして以下の画面が表示されるか動作確認する。

![確認画面 2019-07-29 15.26.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/eeca90e2-2a87-5f36-f3de-9279e0b649aa.png)



6.確認できたら、一度Control+cで止める。
7.ディレクトリ内のfunctions内にある、pacakage.jsonの名前をpackage_bak.jsonに変更
　-ファイル名はなんでもいいです。次のexpressインストール時に上書きされてしまうので、バックアップを取っておく。
8.Functionsディレクトリ内で、次のコマンドでExpressをインストールする

```
$ npm install express --save
```

9.次のコマンドでexpress-generatorを使ってejsをインストールする

```
$ express --view=ejs
```
destination is not empty, continue? [y/N]
と聞かれたら、yを入力しEnter

　-express-generatorをまだインストールしていない場合

```
$ npm install express-generator -g
$ express --view=ejs
```

10.packages.jsonを開き、先ほど取っておいたpackages.jsonのバックアップのscriptsとdependenciesのfirebase関連のものをコピーして新しくできたpackages.jsonにペーストする
(2020.5.2追加)node8が使えるようになったため、enginesもコピペしておく。

```
"scripts": {
    "serve": "firebase serve --only functions",//ここをコピペ
    "shell": "firebase functions:shell",//ここをコピペ
    "start": "npm run shell",//ここをコピペ
    "deploy": "firebase deploy --only functions",//ここをコピペ
    "logs": "firebase functions:log"//ここをコピペ
  },
"engines": {//ここをコピペ
    "node": "8"//ここをコピペ
  },//ここをコピペ
  "dependencies": {
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.9",
    "ejs": "~2.5.7",
    "express": "~4.16.0",
    "http-errors": "~1.6.2",
    "morgan": "~1.9.0",
    "firebase-admin": "~7.0.0",   //ここをコピペ
    "firebase-functions": "^2.2.0"//ここをコピペ
  }
```
　この際scriptsの"start": "node ./bin/www"は削除

11.functions内のindex.jsにapp.jsをまるごとコピペして、app.jsを削除
12.index.jsの1行目に以下を記載

```
var functions = require('firebase-functions');
```

13.index.jsの最終行をコメントアウトまたは削除して、以下に変更

```
// module.exports = app;から以下に変更
exports.app = functions.https.onRequest(app);
```

14.cd ../で1階層上に戻り、firebase.jsonのpublicとignoreの間にrewritesを追加する

```
"rewrites": [{
      "source": "/**",
      "function": "app"
    }],
```
15.functionsディレクトリに戻り、npm installする

```
$cd functions
$npm install
```

16.次にfirebaseでは動的コンテンツよりも静的コンテンツが優先されるため、静的コンテンツのファイルを削除しておく必要があります。静的ファイルはpublicフォルダに保存されているのでこれを削除(2019.9.30復活)

```
$ cd ../
$ rm -rf public/*
```
→firebase tools 7.2.2では、publicがなくなり、index.htmlだけになったので、プロジェクトフォルダ直下のindex.htmlを削除すればいい(2019.8.3)
→firebase tools 7.4.0では、publicが復活したので、以前同様publicフォルダ内の静的コンテンツを削除する必要があります(2019.9.30)

17.firebaseサーバを起動させて、以下の画面が出るかどうか確認する

![スクリーンショット 2019-09-30 13.28.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/f0740da4-09ba-242b-1120-a0e5f9ad29ef.png)


```
$ firebase serve --only functions,hosting
```

18.functionsエミュレーターのfirebase-functions-testをインストールしろと言われるので、functionsディレクトリに移動して、以下のコマンドでインストール(2019.9.30復活)

```
$ npm install --save-dev firebase-functions-test
```
→firebase tools 7.2.2では不要になったようです。(2019.8.3)
→firebase tools 7.4.0では復活したので、インストールする必要があります。(2019.9.30)
→firebase tools 7.6.1では不要になったようです。(2019.10.26)

19.http://localhost:5000 にアクセスして動作確認して、以下の画面が表示されればOK


![確認画面 2019-07-29 15.35.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/476acdd8-8dc7-a354-c5cf-07249e032674.png)

20.あとは、色々弄ってデプロイするだけです。

```
$ firebase deploy
```