🔖

Firebase Cloud Functions の functions.https.onCall の存在に気づいていなかった件

2022/09/09に公開

こんにちは。地図パズル製作所の都島です。今日は Firebase Cloud Functions の functions.https.onCall について書きたいと思います。「呼び出し可能関数」と呼ぶらしいです。というのも、これまで私都島は、この functions.https.onCallの存在自体気づいていませんでした。これまで、Firebase を使いまくっているのに、全く見落としていたとは、、、恥ずかしい。。。

ちなみに functions.https.onCall のドキュメントですが、こちらにあります。

https://firebase.google.com/docs/functions/callable?hl=ja

それでまず、気づいていなかった言い訳を致しますと、、Firebase のドキュメントは全体的に読みやすいですが、このドキュメントは理系の私にはとても難しいです。。(翻訳した方、ごめんなさい。。)なので理解できずに読み飛ばしていたのではないかと思います。きっと私以外にも読み飛ばしていた方がいるはず!と思っています。

ということで今回は、functions.https.onCall をちょっとだけ使ってみた所感を書きたいと思います。

Cloud Functions で API を作るもう一つの方法

まず、Cloud Functions で API を作る方法ですが、二通り方法があります。functions.https.onRequest と functions.https.onCall です。functions.https.onRequest はサンプルでも Express を使ったやり方が紹介されていますし、一般的な node.js でできた APIなどを Firebase に展開するときに使うのではでないかという感じがします。既存の node.js サーバーを Cloud Functions に移行する場合に使えそうです。でも、1年ほど前に私が functinos.https.onRequest で Next.js の SSR を動かしてみたところ、遅くて使い物になりませんでした。たぶん、Express でも同じではないかと思いますので、注意してお使いください。

なお、少し前から Cloud Functions v2 が公開プレビューされています。こちらにバージョンアップされると、早くなるのではないかと期待しております。少し前にこちらの記事がバズっていましたが、こちらも v2 を裏で使っているようですね。

https://zenn.dev/masakasuno1/articles/0988d547ab1de8

functions.https.onCall(呼び出し可能関数)

それに対して、 functions.https.onCall は一般の node.js アプリを firebase に展開するというよりも、バリバリ Firebase を使っている人向け、という感じがします。API にアクセスするのも、クライアントサイドの Firebase SDK を使ってアクセスします。クライアントのソースコードはこんな感じです。

export const registerUserInfo = async (
  functions: Functions,
  handle: string
): Promise<UserProfileResult> => {
  const changeHandle = httpsCallable(functions, "changeHandle");
  const response = await changeHandle({ handle });
  if (typeof response.data !== "string") {
    return "Error";
  }
  if (
    response.data === "Success" ||
    response.data === "Fail" ||
    response.data === "Error"
  ) {
    return response.data;
  }
  return "Error";
};

Frebase Authentication や AppCheck とも簡単に連携ができるので、ユーザー認証や APIの保護をとても簡単に実装できます。サーバー側のソースコードはこんな感じです。

export const changeHandle = functions
  .region("asia-northeast1")
  .runWith({
    secrets: ["COGNITIVE_SERVICES_KEY"],
    allowInvalidAppCheckToken: false,
  })
  .https.onCall(async (data, context): Promise<UserProfileResult> => {
    if (context.app == undefined) {
      throw new functions.https.HttpsError(
        "failed-precondition",
        "The function must be called from an App Check verified app."
      );
    }
    if (typeof data.handle !== "string") {
      return "Error";
    }
    const handle = data.handle as string;
    if (context.auth == null) {
      return "Error";
    }
    const userId = context.auth.uid;
    const key = process.env.COGNITIVE_SERVICES_KEY;
    const result = await db.runTransaction(async (transaction) => {
      const result = await checkHandle(db, transaction, userId, handle, key);
      if (result === "Success") {
        await updateHandle(auth, db, transaction, userId, handle);
      }
      return result;
    });
    return result;
  });

functions.https.onCall で同じ機能を実装しようと思ったら、、本当に大変ですよね。

最後に

ということで、今日は functions.https.onCall を使ってみた所感を書きました。私みたいに存在に気づいていなかった人も、きっといるはず!!と思っていますが、そういう方はぜひ使ってみてください。

最後にいつものように、地図パズル製作所の宣伝をさせていただきます。地図パズル製作所では楽しい地図パズルをたくさん公開していて、Firebase を使って作られています。一度やるとはまっちゃうかも??ぜひ、やってみてください!

https://chizu-puzzle.com/

Discussion