[Firebase] CloudFunctionsのRESTful APIを独自ドメインで利用する

小ネタです。

FirebaseでCloudFunctionsを利用してRESTful APIを作成していると、通常はhttps://[Region]-[ProjectID].cloudfunctions.net/[関数名]といったURLになるわけですが、これを独自ドメインで運用したい、またはパスを変更したい場合の設定方法です。

CloudFunctionの準備

まずはCloudFunctionで適当なコードを用意します。

const functions = require("firebase-functions");

exports.sayGroot = functions.https.onRequest( (req, res) => {
  res.send("<h1>I am Groot</h1>");
});

このままdeployするとhttps://us-central1-test-f76bc.cloudfunctions.net/sayGrootといったURLで実行することになります。これを独自ドメインかつパスもかっこよくしたい!あわよくば5000兆円もほしい!

Hosting設定

上記URLのドメインとパスを変更するにはHostingと連携する必要があります。

独自ドメイン

独自ドメインの設定方法については過去記事の「独自ドメインを設定する」の項目を参照ください。 blog.katsubemakito.net

rewritesでCloudFunctionと連携

Firebase.jsonをテキストエディタで開き、以下のようにrewritesの項目を追加します。

{
  "hosting": {
    "public": "public",
    "rewrites": [ {
      "source": "/say/groot", "function": "sayGroot"
    }],
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}

これによりhttps://[独自ドメイン]/say/grootへリクエストが来ると、自動的にCloudFunctionのsayGroot関数が実行されるようになります。

最後にfirebase deployすれば設定が反映されます。めっちゃ簡単ですね。

その他

設定前のURLも有効

Hostingで設定するrewriteはエイリアスのような物です。今回の設定したからと言ってオリジナルのURLが利用できなることはありません。 https://us-central1-test-f76bc.cloudfunctions.net/sayGroot

複数同時に指定

REST APIを以下のように複数用意した場合です。

exports.sayGroot = functions.https.onRequest( (req, res) => {
  res.send("<h1>I am Groot</h1>");
});
exports.sayNyanpass = functions.https.onRequest( (req, res) => {
  res.send("<h1>にゃんぱすー</h1>");
});

Firebase.jsonrewritesはこんな感じ。

"rewrites": [
  {"source": "/say/groot", "function": "sayGroot"},
  {"source": "/say/nyanpass", "function": "sayNyanpass"}
],

PATH_INFOを受け取る

いわゆるPATH_INFOはreq.pathに入って来ますので、これを/などでsplit()して利用します。

exports.sayEcho = functions.https.onRequest( (req, res) => {
  let path = req.path.split("/").slice(3).join(" ");
  res.send(`<h1>${path}</h1>`);
});

Firebase.jsonは以下の通り。ワイルドカードであるアスタリスク(*)をお尻に2つ付けてやります。

"rewrites": [
  {"source": "/say/echo/**", "function": "sayEcho"}
],

ワイルドカードが1つだけだと/say/echo/fooはリダイレクトしてくれますが、/say/echo/foo/barのように2つ以上の階層はNotFoundになってしまいます。

リージョンの指定はできない

CloudFunctionsもHostingも無指定だと北米リージョンになります。日本国内のサービスであれば東京リージョンで動かしたいところです…が、今回の方法を利用した場合、結論から言うと現状はできません。

重要: HTTP 関数を使用して Firebase Hosting で動的コンテンツを提供するには、us-central1 を使用する必要があります。

firebase.google.com

残念すぎる(´・ω・`) Firebaseは大変便利なんですけど、いざ突っ込んだことをしようとするとこういう目によく会うんですよね…。将来的に東京リージョンでも動かせることを祈ります。

参考ページ