Cloud Functions をまとめてデプロイしたら、Realtime Database のトリガーだけが4つとも失敗しました。エラーは cannot create a trigger in region asia-northeast1。原因も対処も単純でしたが、そのとき見つかった副次的な問題のほうが深刻だったので、あわせて書きます。
01 — 原因
DB のリージョンとトリガーのリージョンは一致させる
Cloud Functions 2nd gen の RTDB トリガー(onValueCreated / onValueWritten)は、
データベースインスタンスと同じリージョンにしか作成できません。
当時のデータベースは *.firebaseio.com ドメイン、つまり us-central1 にありました。
関数側は規約として asia-northeast1 に統一していたので、そこにトリガーを作ろうとして弾かれていた、という話です。
対処は、該当する関数にだけリージョンを明示することでした。 onCall / onRequest / スケジューラなど他の関数は asia-northeast1 のままで問題ありません。
// RTDBトリガーだけ DB と同じリージョンを明示する
const RTDB_TRIGGER_REGION = 'us-central1';
exports.sendMessageNotification = onValueCreated(
{ ref: '/messages/{roomId}/{msgId}', region: RTDB_TRIGGER_REGION },
async (event) => { ... }
);
02 — 見つかってしまったこと
その4つは、一度も動いていなかった
デプロイのログをよく見ると、この4関数の表示が creating でした。更新ではなく新規作成です。
つまり本番環境で、プッシュ通知も、引き継ぎコードのハッシュ化も、受信数の加算も、一度も実行されていなかったということです。
エラーは出ていませんでした。ただ、動いていなかっただけです。
個人開発でいちばん怖いのはこの壊れ方だと思っています。
落ちてくれれば気づけますが、「静かに何もしていない」状態はログを読みに行かない限り分かりません。
デプロイ時に creating と出た関数は、意図した新規かどうかを必ず確認するようにしました。
03 — DBを移すときの注意
接続先は2箇所ある
その後、リリース前でデータ移行がゼロのうちに、データベースを asia-southeast1 へ移しました。 このとき注意が要ったのは、アプリが見る接続先とサーバーが見る接続先は別々に書かれていることです。
| アプリ側 | main.dart で databaseURL を上書き。設定ファイル自動生成の値はデフォルトインスタンスを指すため、そのままでは旧DBを見ます。 |
|---|---|
| Functions側 | initializeApp({ databaseURL }) の値。 |
| トリガー | 新リージョンへ再デプロイし、instance も明示。未指定だと同一リージョンの全インスタンスにマッチします。 |
| 他の関数も | initializeApp の変更は全関数に効くので、トリガー以外もまとめて再デプロイが必要です。 |
片方だけ変えると、アプリとサーバーが別のデータベースを見るという分かりにくい事故になります。必ず同時に変えてください。
Follow
こういう記録を置いています
個人開発でつまずいた話や、作りかけのものは Instagram(@kenpiro1012)と note にも置いています。 記事の一覧は記事ページにまとまっています。