Cloud Functions for Firebase上でExpressを動かす

## Cloud Functions for Firebase ってなに？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/a7e5ec79-e786-3861-e3d3-3608011de841.png)
データベースへの書き込みやHTTPSリクエストなどのイベントをトリガーにしてコードを実行できる機能であり、サポート言語としては、 Node.js のみとなっています。
※色々やればPythonやGoも使えるらしい（未検証）

## firebase コマンドの導入
firebase-toolsとは、Firebaseプロジェクトの管理、表示、デプロイ等ができます。

```
# firebase toolをインストール
npm install -g firebase-tools
```

## firebase ログイン
ブラウザが起動しポップアップが表示されるので使用したいgooogleアカウントでログイン

```
firebase login
```
実際のログイン画面の様子
![ezgif-2-f7fa6e6c9e77.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/924a7ed7-db94-1345-912f-472cb6030063.gif)

## Firebaseプロジェクト作成(GUI上)
[Firebaseコンソールを開く](https://console.firebase.google.com/u/0/)

まず、コンソール画面にてプロジェクトの追加をクリックします。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/ea313196-f98c-a402-86c6-9b2eb788fe58.png)

任意のプロジェクト名を入力して続行を押します。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/bef5c25d-a60b-01c1-5f85-cf1f2964c6ea.png)

次の画面でも続行を押します。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/eb76406d-da06-ef0a-f322-249e8564a47d.png)

次のような画面が出ればプロジェクトが作成され完了します。
![スクリーンショット 2020-10-23 23.45.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/17588abe-9134-94a9-d646-0131014cf016.png)

## プロジェクトを初期化(Firebaseプロジェクト作成)
構築するディレクトリに移動し、firebase initを実行します。
構築するディレクトリに指定はありません。今回はデスクトップ上にexpress_project名前でからディレクトリを作りました。

```
$ cd Desktop
$ mkdir express_project
$ cd express_project
$ firebase init
```
以上のコマンドを実行すると次のようなコンソールが出るのでスペースキーで利用するサービスを選択します。
(利用するサービスは複数選択することができます。)
選択し終えたらエンターを押し次へと進みます。
![スクリーンショット 2020-10-24 0.02.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/69107842-5024-423e-eb31-fc76c662ee80.png)

先ほど作成したプロジェクトを選択するので `Use an existing project `を選択します。

```
? Please select an option: (Use arrow keys)
❯ Use an existing project 
  Create a new project 
  Add Firebase to an existing Google Cloud Platform project 
  Don't set up a default project 
```
そうすると作成したプロジェクトが表示されるので該当するプロジェクトを選択します。

```
? Select a default Firebase project for this directory: (Use arrow keys)
❯ express-2c5fa (Express-test) 
```
どの言語使う？使うか聞かれます。本来であれば静的言語(TypeScript)を使いたいですが、初回なのでJavaScriptを選択します。

```
=== 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? (Use arrow keys)
❯ JavaScript 
  TypeScript 
```

ESLintを使用するか聞かれますが今回はnoで大丈夫なのでそのままEnterを押してください。

```
? Do you want to use ESLint to catch probable bugs and enforce style? (y/N) 
```

依存ファイル入れるかを聞かれるのでここではyを入力しEnterを押してください。

```
? Do you want to install dependencies with npm now? (Y/n) 
```
最終的に以下のような画面が表示されれば完了です。
![スクリーンショット 2020-10-24 0.11.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/d69f3630-0e66-611b-c537-23724de9be80.png)

作業ディレクトリ直下に、functionsディレクトリができており、その中にindex.jsができてるので、それを編集していきます。

```
$ ls
firebase.json	functions
$ cd functions/
$ ls
index.js		package-lock.json
node_modules		package.json
```

## Expressの導入
・ ExpressはNode.jsのフレームワーク．
・ APIのエンドポイントを手軽に実装できるので便利．

下記コマンドを実行してインストールしていきます。
※引数 --save は依存関係リストに保存することを意味します。

```
npm install express --save
```
インストール後の画面はこんな感じです。
![スクリーンショット 2020-10-24 0.21.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/bdb08e3b-9e93-6d7c-1ee3-f45bf7b7ea08.png)

インストールが終わったらindex.jsを編集していきます。
お使いのエディターでindex.jsを以下のように編集していきます。

```
// Expressの読み込み
const express = require("express");

const app = express();

app.get('/hello', (req, res) => {
  // レスポンスの設定
  res.send('Hello Express!');
});

// 出力
const api = functions.https.onRequest(app);
module.exports = { api };
```
自分自身はWebStormを使っているのでこんな感じの画面になります。
![スクリーンショット 2020-10-24 0.25.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/60c4e127-2257-63f3-d5e3-c0c34f5db4b9.png)

## デプロイ
デプロイしていきます！と言いたいところですが実はnodev10というのが最新ではありますが、有料課金設定を行わなければなりません。なので今回はテストということでnode v8を使っていきます。

しかし注意して欲しいのがNode.js 8が非推奨になり2021年の3月中旬には全面的にサポートされなくなるので本番環境や実サービスなどでは利用しないようにしてください。

functionsフォルダー内のpackage.jsonの`engines`の部分を 10　→ 8 に書き換えます。

```package.json
  "engines": {
    "node": "8"
  },
  "main": "index.js",
  "dependencies": {
    "express": "^4.17.1",
    "firebase-admin": "^8.10.0",
    "firebase-functions": "^3.6.1"
  },
  "devDependencies": {
    "firebase-functions-test": "^0.2.0"
  },
  "private": true
}

```

そしてデプロイを行います。

```
firebase deploy --only functions
```
完了するとこのような画面が出るので発行されたURLをクリックし、Expressが起動するか確認します。
![スクリーンショット 2020-10-24 0.40.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/ca74cb94-46a0-f2af-e2b9-86830a68fb55.png)

アクセスすべきURLは以下のような/apiで終わるURLです。

```
Function URL (api): https://us-central1-express-2c5fa.cloudfunctions.net/api
```
※以下のURLの後に/helloをつけるのを忘れないように
![スクリーンショット 2020-10-24 0.43.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817075/a34f9f8a-a433-b40e-127f-ea96ece7d78b.png)

以下で終了です！お疲れ様でした。

# 参考にさせていただいた記事
・[わかる！Firebase ～全てのサービスをおつまみ紹介～ - Qiita](https://qiita.com/dogwood008/items/fa95b62ad151f823af70)
・[5分でサーバレスを体験！ Cloud Functions for Firebase を使ってみよう ｜ SiTest (サイテスト) ブログ](https://sitest.jp/blog/?p=11553)
・[Cloud Functions 最低限（セットアップ＋HTTPトリガー） - Qiita](https://qiita.com/zaburo/items/fa810a22cc132ae1317d)
・[Cloud Functions + ExpressでサーバレスAPIを実装](https://taroosg.io/cloud-functions-express)