Cloud Functions for FirebaseとFirebase Hostingを試してみる

## やること

Cloud Functions for FirebaseとFirebase Hostingを試してみようと思います。
html/cssの静的ファイルのデプロイ、jsファイルの動的ファイルのデプロイ、html/css/jsの動的サイトのデプロイ、の3パターンを試してみようと思います。

## Firebaseを使うための準備

Firebase CLIをインストールとログインをします。

```bash
~$ npm i -g firebase-tools
```

インストールが完了したらプロジェクトディレクトリを作成＆移動してFirebaseにloginします。

```bash
~$ mkdir firebase-sample
~$ cd firebase-sample
~$ firebase login
```

loginしたらFirebase ConsoleでFirebaseプロジェクトを作成しておきます。今回は「myproj」という名前で作っておきましょう。
Firebaseプロジェクトを作成したらinitしていきます。

```bash
~$ firebase init
```

設定内容は以下の通りでです。  

* features：FunctionsとHosting
* Option：Use an existing project
* Firebase project for this directory：myproj
* language：JavaScript
* use ESLint：n
* install dependencies with npm now：y
* use as your public directory：public
* Configure as a single-page app：y

## 静的ファイルのデプロイと動的ファイルのデプロイ

ちょっと手抜きをして静的ファイルのデプロイと動的ファイルのデプロイを一緒にやっていきます。  
initが完了したら諸々ファイルが作られていると思います。funtionsに動的ファイル、publicに静的ファイルを配置します。init後はそれぞれサンプル的なファイルが配置されていると思います。/functions/index.jsを以下のように書きまえます（コメントを外すだけです）。

```js
const functions = require('firebase-functions');

// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
exports.helloWorld = functions.https.onRequest((request, response) => {
  response.send("Hello from Firebase!");
});
```

次にfirebase.jsonを以下のように修正します。rewritesにオブジェクトを追加しているだけです。

```json
{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "/hello",
        "function": "helloWorld"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}
```

firebase.jsonを修正したらプロジェクトをローカルで動かしてみましょう。

```bash
~$ firebase serve
```

サーバが起動したらlocalhost:5000にアクセスして/public/index.htmlの内容が表示、localhost:5000/helloにアクセスして「Hello from Firebase!」を表示されていればローカルでの動作確認OKです。

Firebaseにデプロイする前に/public/style.cssを作成し、HTMLを書き換えましょう。

```css
body {
    background-color: antiquewhite;
}
```

```html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Firebase hosting sample</title>
    <link rel="stylesheet" href="./style.css">
</head>

<body>
    <p>index.html</p>
</body>

</html>
```

先程と同じようにローカルで確認して問題が無ければ以下のコマンドでデプロイしましょう。

```bash
~$ firebase deploy
```

デプロイが完了したらTerminalにHosting URLが表示されていると思うのでアクセスして先程修正したHTMLが表示されていれば静的ファイルのデプロイはOKです！  
[Hosting URL]/helloにアクセスして「Hello from Firebase!」と表示されていれば動的ファイルのデプロイもOKです！

## 動的サイトのデプロイ

動的サイトはExpressで作成していきます。必要なPackageをインストールします。インストールする時にfunctionsディレクトリに移動するのを忘れないでください。

```bash
~$ cd functions
~$ npm i express jade
```

それでは動的サイトをササッと作っていきましょう。ExpressやJadeの詳細は割愛します。

/functions/index.jsを以下のように修正します。

```js
const functions = require('firebase-functions');
const express = require('express');
const path = require('path');

const app = express();
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "jade");
app.get('/jade', function(req, res){
  res.render('sample', { message: 'Hello Jade!!' });
});

exports.site = functions.https.onRequest(app);
```

firebase.jsonを以下のように修正します。

```json
{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**/*",
        "function": "site"
      }
    ]
  }
}
```

/functionsにviewsディレクトリを作成し、/functions/views/sample.jadeを追加して以下のコードを貼り付けます。

```jade
doctype
html(lang="ja")
  head
    title Web site!!
    link(rel='stylesheet', href='style.css')
  body
    p= message
```

ローカルで動かしてlocalhost:5000/jadeにアクセスして「Hello Jade!!」と表示されていれば動作確認OKです！firebaseにデプロイして同じ挙動になるか動作してみましょう！

## おわり

Firebase Realtime DBも試してみたいし、GitHub Actions使って自動デプロイとかもやってみたい。