[Firebase] us-central1以外にデプロイしたhttpsCallable関数を呼び出す際には..

2 min read読了の目安(約1900字

ちょっと詰まったのでメモ。

別リージョンにデプロイしたhttpsCallable関数の呼び出しに失敗する?

以下のようにasia-northeast1に httpsCallable 関数をデプロイしてアプリ側から呼ぶコードを書きました。

◆function 側

export const foo = functions
  .region("asia-northeast1")
  .https.onCall(async (data, context) => {
    // ...
  })

◆アプリ側

const functions = firebase.functions();

// fooはasia-notheast1のregionのhttpsCallable関数で呼び出される
const foo = functions.httpsCallable("foo");
foo({ /* ... */ }).then(/* ... */)

特になにも問題はないように見えるのですが、アプリ側から Cloud Functions for Firebase の httpsCallable 関数を呼び出したとき以下エラーで失敗してしまいました。

Access to fetch at 'https://us-central1-trigger-email-sample.cloudfunctions.net/foo' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

一見 CORS っぽいエラーなのですが、よく見ると関数の実行先がhttps://us-central1-xxxとなっています。
これでは region が違うので関数が見つかりません。

ドキュメントにも以下の記載がありました。どうやらus-central1以外にデプロイしている場合はアプリ側で region の設定が必要なようです。

Note: To call a function running in any location other than the default us-central1, you must set the appropriate value at initialization. For example, on Android you would initialize with getInstance(FirebaseApp app, String region).

https://firebase.google.com/docs/functions/callable

解決策

以下のように firebase 初期化時に region をつけることで解決しました。
通常のようにfirebase.functions()ではなくfirebase.app().functions()とする必要があるので注意です。

const functions = firebase.app().functions('asia-northeast1');

// fooはasia-notheast1のregionのhttpsCallable関数で呼び出される
const foo = functions.httpsCallable("foo");
foo({ /* ... */ }).then(/* ... */)

参考