コピペで使うFirebase【Cloud functions編】

# 概要
Cloud functionsを使う際にコピペで動かしたいのでそのまとめです。

**公式ドキュメント**
[Cloud Functions for Firebase](https://firebase.google.com/docs/functions/)
[HTTP トリガー](https://firebase.google.com/docs/functions/http-events)
[Storage トリガー](https://firebase.google.com/docs/functions/gcp-storage-events)
[Firestore トリガー](https://firebase.google.com/docs/functions/firestore-events?hl=ja) 
[Authentication トリガー](https://firebase.google.com/docs/functions/auth-events?hl=ja)
[Analytics トリガー](https://firebase.google.com/docs/analytics/extend-with-functions?hl=ja)
[スケジュール](https://firebase.google.com/docs/functions/schedule-functions?hl=ja)

# トリガー
- [HTTP](#http)
  - onRequest
     - [リクエスト(onRequest)](#リクエストonrequest)
     - [GET, POST](#get-post)
     - [クエリーパラメータ取得](#クエリーパラメータ取得)
  - onCall（認証情報が取得できる）
     - [リクエスト(onCall)](#リクエスト(onCall))
     - [認証情報取得](#認証情報取得)
     - [パラメータ取得](#パラメータ取得)
- [Storage](#storage)
  - [正常に作成された場合](#正常に作成された場合)
  - [削除された場合](#削除された場合)
- [Firestore](#firestore) 
  - [新しいドキュメントが作成されたとき](#新しいドキュメントが作成されたとき)
  - [ドキュメントが更新されたとき](#ドキュメントが更新されたとき)
  - [ドキュメントが削除されたとき](#ドキュメントが削除されたとき)
- [Authentication](#authentication)
  - [ユーザー作成時](#ユーザー作成時)
  - [ユーザー削除時](#ユーザー削除時)
- [Analytics](#analytics)
  - [イベント発火時](#イベント発火時)
- [Scheduler](#scheduler)
  - [設定したタイミングで実行](#設定したタイミングで実行)

## HTTP
### リクエスト(onRequest)
`<functions url>/httpEvent`

```js
exports.httpEvent = functions.https.onRequest((req, res) => {
    res.status(200).send(/* params */)
});
```
### GET, POST
`<functions url>/httpEvent`

```js
exports.httpEvent = functions.https.onRequest((req, res) => {
    switch (req.method) {
        case 'GET':
            /* ... */
            break
        case 'POST':
            /* ... */
            break
        default:
            res.status(400).send("error")
            break
    }
});
```
### クエリーパラメータ取得
`<functions url>/httpEvent?param=1234`

```js
exports.httpEvent = functions.https.onRequest((req, res) => {
    const param = req.query.param;
    res.status(400).send(param)
});
```

### リクエスト(onCall)
※firebaseSDKの`httpsCallable`で呼び出す必要がある。

```js:呼び出し
const httpEvent = firebase.functions().httpsCallable('httpEvent');
httpEvent().then((res) => {
  console.log(res); // { message: success }
});
```
```js
exports.httpEvent = functions.https.onCall((data, context) => {
  return { message: success };
})
```

### 認証情報取得

```js:呼び出し
const httpEvent = firebase.functions().httpsCallable('httpEvent');
httpEvent().then((res) => {
  console.log(res); // { message: success }
});
```
```js
exports.httpEvent = functions.https.onCall((data, context) => {
  // 認証済みであれば認証情報がcontext内に存在する
  if (context.auth) {
    console.log(context); // { auth: { ... } }
  } else {
    console.log(context); // { ... }
  }
  return { message: success };
})
```

### パラメータ取得

```js:呼び出し
const httpEvent = firebase.functions().httpsCallable('httpEvent');
httpEvent({ text: hello }).then((res) => {
  console.log(res); // { message: hello }
});
```
```js
exports.httpEvent = functions.https.onCall((data, context) => {
  // 認証済みであれば認証情報がcontext内に存在する
  console.log(data.text); // hello
  return { message: data.text };
})
```

## Storage
### 正常に作成された場合

```js
exports.registeredFile = functions.storage.object().onFinalize((object) => {
    const fileBucket = object.bucket; // バケットのフルパス
    const filePath = object.name; // ファイルまでのパス
    const contentType = object.contentType; // ファイルのタイプ
    const metageneration = object.metageneration; //　メタデータのバージョン？(メタデータが変更されるたびに増えていく)
})
```

### 削除された場合

```js
exports.deleteFile = functions.storage.object().onDelete((object) => {
    const fileBucket = object.bucket; // 削除したバケットのフルパス
    const filePath = object.name; // 削除したファイルまでのパス
    const contentType = object.contentType; // 削除したファイルのタイプ
    const metageneration = object.metageneration; //　削除したメタデータのバージョン
})
```

## Firestore
### 新しいドキュメントが作成されたとき

```js
exports.create = functions.firestore.document('<Collection名>/{ID}').onCreate((snap, context) => {
    const createdValue = snap.data(); // 作成したデータ
})
```

### ドキュメントが更新されたとき

```js
exports.update = functions.firestore.document('<Collection名>/{ID}').onUpdate((snap, context) => {
    const newValue = snap.after.data(); // 更新後のデータ
    const previousValue = snap.before.data(); // 更新前のデータ
})
```

### ドキュメントが削除されたとき

```js
exports.delete = functions.firestore.document('<Collection名>/{ID}').onDelete((snap, context) => {
    const deletedValue = snap.data(); // 削除したデータ
})
```

## Authentication
### ユーザー作成時

```js
exports.createUser = functions.auth.user().onCreate((user) => {
    const email = user.email; // email
    const displayName = user.displayName; // user name
});
```

### ユーザー削除時

```js
exports.deleteUser = functions.auth.user().onDelete((user) => {
    /* ... */
});
```

## Analytics
イベントをトリガーにする場合はコンバージョンとしてマークする必要あり。
コンソール → アナリティクス → 「コンバージョンとしてマークを付加」

### イベント発火時

```js
exports.event = functions.analytics.event('<イベント名>').onLog((event) => {
  const user = event.user; // イベントを発火したユーザーの情報
  const { /* ... */ } = event.param; // イベントに設定してあるパラメーター
/* ... */
});

```

## Scheduler
### 設定したタイミングで実行
時間の指定については以下記事を参考
[Cloud FunctionsをCrontabで定期実行する方法](https://qiita.com/jnchito/items/215c2d51599eb29adabc)

```js
scheduler = functions.pubsub.schedule('<時間>').onRun((context) => {
/* ... */
});
```

### 時間のタイムゾーンを「Asia/Tokyo」で指定する場合
日本時間14時に関数を実行

```js
scheduler = functions.pubsub.schedule('0 14 * * *').timeZone("Asia/Tokyo").onRun((context) => {
/* ... */
});
```