mokajima.com

Cloud Functions と Firebase Hosting で動的コンテンツを提供する場合は関数の実行リージョンを指定できない

はじめに

Cloud Functions の関数はデフォルトでは us-central1 リージョン(アイオワ)で実行されます。プログラム上で実行リージョンを指定することも可能で、その場合は region() メソッドを使います。

以下の例では functions.https を使い app という名前の HTTP 関数を定義しています。HTTP 関数とは HTTP リクエスト経由で呼び出される関数のことです。

const functions = require('firebase-functions')

exports.app = functions
  .region('asia-northeast1')
  .https
  .onRequest((req, res) => { /* ... */ })

onRequest((req, res) => { /* ... */ }) に HTTP リクエストを受け取った際の処理を記述します。region('asia-northeast1') によって app()asia-northeast1 リージョン(東京)で実行されます。

このように region() メソッドを使うことで関数の実行リージョンを指定することが可能です。日本国内で展開するプロジェクトの場合、asia-northeast1 リージョン(東京)や asia-northeast2 リージョン(大阪)を指定することが多いでしょう。

関数の実行リージョン指定の注意点

region() メソッドを使うことで関数の実行リージョンを指定できるのですが、1つ注意点があります。それは Cloud Functions と Firebase Hosting を使って動的コンテンツを提供する場合は、その Cloud Functions の関数の実行リージョンはデフォルトである us-central1 リージョン(アイオワ)しか使用できない、ということです。

サンプルコード

Cloud Functions と Firebase Hosting を使って動的コンテンツを提供する例として、サイトに Basic 認証をかけるシンプルなプロジェクトを作成しました。ソースコードはこちらです。

https://github.com/mokajima/firebase-basic-authentication

実際に試してみたい場合は以下の手順を実行してください。

  1. git clone https://github.com/mokajima/firebase-basic-authentication.git を実行
  2. functions ディレクトリ内の依存パッケージをインストール
  3. .firebaserc.sample.firebaserc にリネーム
  4. .firebasercdefault プロパティの値をご自身の Firebase プロジェクトのプロジェクト ID に書き換える
  5. firebase deploy を実行

firebase deploy を実行すると Firebase プロジェクトのデプロイが行われます。デプロイ完了後にサイトにアクセスすると Basic 認証のポップアップが表示され、認証後に「You passed」の文字が表示されます。

app() の実行リージョンを asia-northeast1 リージョン(東京)に変更

次に、 region() メソッドを使って app() の実行リージョンを us-central1 リージョン(アイオワ)から asia-northeast1 リージョン(東京)に変更してみましょう。

サンプルコードの functions/index.js を次のように書き換えます。

-exports.app = functions.https.onRequest(app)
+exports.app = functions.region('asia-northeast1').https.onRequest(app)

変更を保存し、firebase deploy を実行します。このとき us-central1 リージョン(アイオワ)の app() を削除するかどうか聞かれますが yes としてください。

$ yarn deploy

The following functions are found in your project but do not exist in your local source code:
	app(us-central1)

If you are renaming a function or changing its region, it is recommended that you create the new function first before deleting the old one to prevent event loss. For more info, visit https://firebase.google.com/docs/functions/manage-functions#modify

? Would you like to proceed with deletion? Selecting no will continue the rest of the deployments. (y/N)

デプロイ完了後、サイトにアクセスしてみてください。Google アカウントのログイン画面にリダイレクトされてしまい、正しくサイトが動いていないことがわかります(そのブラウザで Google アカウントにログイン済みの場合は別の画面が表示されます)。

Chrome DevTools の Network タブで確認してみると、以下のような URL にリダイレクトされているようです(Firebase のプロジェクト ID が firebase-basic-authentication の場合)。

挙動を確認したら、サンプルコードの functions/index.js の記述を元に戻しておきましょう。firebase deploy を再実行し、デプロイ完了後にサイトにアクセスすると正しい挙動に戻ります。

-exports.app = functions.region('asia-northeast1').https.onRequest(app)
+exports.app = functions.https.onRequest(app)

このように、Cloud Functions と Firebase Hosting を使って動的コンテンツを提供する場合、Cloud Functions の関数の実行リージョンはデフォルトである us-central1 リージョン(アイオワ)以外は使用できません。

公式ドキュメントにも次のように記述されており、2021 年 1 月現在もその制限は続いています。

重要:HTTP 関数を使用して Firebase Hosting の動的コンテンツを提供する場合は、us-central1 を使用する必要があります https://firebase.google.com/docs/functions/locations#http_and_client-callable_functions

おわりに

Cloud Functions で関数をデプロイする場合、日本国内で展開するプロジェクトの場合は asia-northeast1 リージョン(東京)や asia-northeast2 リージョン(大阪)を実行リージョンに指定することが多いかと思います。今回の例のように Cloud Functions と Firebase Hosting を使って動的コンテンツを提供する場合は、うっかり region() メソッドを使ってしまうと意図しない挙動となってしまうためご注意ください。

参考