はじめに

Cloud Functions for Firebase を色々と触った際の メモ/Tips。ドキュメントを読んだだけで試せてない(後で試したい)ものもあり。

この記事が参考になった方
ここここからチャージや購入してくれると嬉しいです(ブログ主へのプレゼントではなく、ご自身へのチャージ)
欲しいもの / Wish list

目次

  1. はじめに
  2. 環境・条件
  3. 詳細
    1. Request の情報取得
      1. Request Headers
      2. Query Parameters
    2. リージョン指定
    3. ファイル分割など
    4. CORS エラー対応
    5. ローカルデバッグ
    6. コネクション維持
    7. Optional Chaining(?.)を使いたい
  4. 参考文献

環境・条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ sw_vers
ProductName: macOS
ProductVersion: 11.3.1
BuildVersion: 20E241

$ node -v
v12.7.0

$ npm -v
7.6.3

$ firebase --version
9.10.1

$ npm ls firebase-admin firebase-functions
├── firebase-admin@9.7.0
├── firebase-functions-test@0.2.3
└── firebase-functions@3.13.2

詳細

公式ドキュメントに大体書かれている。

Request の情報取得

参考: HTTP リクエスト経由で関数を呼び出す | Firebase

Request Headers

参考: req.get(field) - Express 4.x - API Reference

onRequest の第一引数 requestExpress の Request なので、request.get で Request Headers の情報を取得可能。

1
2
3
4
5
6
7
const functions = require("firebase-functions");

exports.someFunction = functions
.https.onRequest((request, response) => {
const authorization = request.get('Authentication');
// ...
});

Query Parameters

参考: req.query - Express 4.x - API Reference

1
2
3
4
5
6
7
const functions = require("firebase-functions");

exports.someFunction = functions
.https.onRequest((request, response) => {
const foo = request.query.foo;
// ...
});

リージョン指定

参考:

region('region-name') でデプロイ先のリージョンを指定可能。デフォルトは us-central1 (アイオワ)。

以下は asia-northeast1 (東京)を指定する例。

1
2
3
4
5
6
7
8
const functions = require("firebase-functions");

exports.someFunction = functions
.region("asia-northeast1")
.https.onRequest((request, response) => {
// 何らかの処理
response.send('レスポンス');
});

functions.region() でカンマ区切りの複数のリージョン文字列を渡すことで、複数のリージョンを指定できます。

カンマ区切りで指定すると、複数リージョンを指定できるとのこと、たぶん以下のような感じ(未検証)

1
2
3
exports.someFunction = functions
.region("asia-northeast1,us-east1,europe-west1")
// ...

ファイル分割など

参考: 複数の関数を整理する | Firebase

ざっくり以下の方法でファイル分割できる

  • endpoint ごとにファイルを分けて保存
  • index.js から require する
1
2
3
4
5
6
7
8
9
10
// index.js
const foo = require('./foo');
exports.foo = foo.foo;
// ↑は exports.foo = require('./foo').foo; でも OK

// foo.js
const functions = require('firebase-functions');
exports.foo = functions.https.onRequest((request, response) => {
// ...
});

CORS エラー対応

参考:

response.set'Access-Control-Allow-Origin を設定する。あるいは cors を噛ませる。

1
2
3
4
5
6
7
8
const functions = require("firebase-functions");

exports.someFunction = functions
.https.onRequest((request, response) => {
// 雑に設定しているができる限り適切に制限すべき
response.set("Access-Control-Allow-Origin", "*");
response.send("レスポンス");
});

1
2
3
4
5
6
7
8
9
const functions = require("firebase-functions");
const cors = require("cors")({ origin: true });

exports.headerTest = functions
.https.onRequest((request, response) => {
cors(request, response, () => {
response.send("レスポンス");
});
});

ローカルデバッグ

参考: ローカルでの関数の実行 | Firebase

firebase emulators:start [--only functions] コマンドでローカルサーバが起動。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ firebase emulators:start
i emulators: Starting emulators: functions
✔ functions: Using node@12 from host.
i functions: Watching "/Users/hoge/functions" for Cloud Functions...
✔ functions[sampleFunction]: http function initialized (http://localhost:5001/hoge/sampleFunction).

┌─────────────────────────────────────────────────────────────┐
│ ✔ All emulators ready! It is now safe to connect your app. │
i View Emulator UI at http://localhost:4000 │
└─────────────────────────────────────────────────────────────┘

┌───────────┬────────────────┬─────────────────────────────────┐
EmulatorHost:PortView in Emulator UI
├───────────┼────────────────┼─────────────────────────────────┤
Functionslocalhost:5001 │ http://localhost:4000/functions
└───────────┴────────────────┴─────────────────────────────────┘
Emulator Hub running at localhost:4400
Other reserved ports: 4500

あとは Functions を実行(ブラウザでアクセスするなり、Node.js REPL から API 叩くなり)して挙動を確認できる。


ローカル実行でも firebase-admin を使って Firestore などにもアクセス可能。

1
2
3
4
5
6
7
8
9
10
11
const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp();

exports.sampleFunction = functions
.https.onRequest(async (request, response) => {
const doc = await admin.firestore().doc('/my-collection/my-doc').get();
const data = doc.data();
// ...
response.send("レスポンス");
});

ちなみに http://localhost:4000 にアクセスすると以下のような GUI で情報を確認できる。

コネクション維持

参考:

毎回コネクション確立するとオーバーヘッドがあるので、コネクションを維持できるっぽい。(未検証。試したら追記する)


http ではなく axios を使いたい場合は、以下を参考にすればたぶんいけそう。

Optional Chaining(?.)を使いたい

参考:

Node.js 14 を使えば Optional Chaining(?.)がデフォルトで使えるようになる。ただし、2021/05/08 時点では Node.js 14 はβ版なので注意。

Node.js のバージョンを指定したい場合は functions/package.jsonengines で指定可能。

1
2
3
4
5
6
7
8
{
"name": "functions",
// ...
"engines": {
"node": "12" // *****
},
// ...
}

もしくは Webpack や Babel を使って index.js を出力する感じでもいけそう。以下はChrome 拡張の話だけど、多少は参考にはなるはず。

参考文献

関連記事

この記事が参考になった方
ここここからチャージや購入してくれると嬉しいです(ブログ主へのプレゼントではなく、ご自身へのチャージ)
欲しいもの / Wish list