ブロッキング関数とは?
Firebase Authenticationでは、Cloud Run Functionsの関数を認証時に実行するブロッキング関数という機能が提供されています。
ブロッキング関数は、ユーザーアカウントの作成やログインなどの認証処理のフローを一時的に停止させ、関数の処理が完了するまで待機させます。
以下のような認証関連のイベントごとにブロッキング関数を設定できるので、サインアップ時のFirestoreデータ作成やカスタムクレームの設定、認証中のチェック処理等を行うのに非常に便利です。
- ユーザーが作成される前
- ユーザーがログインする前
- メールの送信前
- SMSメッセージの送信前
なお、ブロッキング関数の利用にはFirebase Authentication with Identity Platformへのアップグレードが必要になります。
7秒のタイムアウト制限
ブロッキング関数は便利な機能ですが、認証処理のフローをブロックするため、タイムアウトが7秒と短めに設定されています。
関数内の処理を7秒以内に収めることはそれほど難しくありませんが、この時間にはCloud Run Functionsのインスタンス起動時間も含まれているため注意が必要です。
Cloud Run Functionsは通常コールドスタンバイ状態にあるため、起動時間が長くなると、タイムアウトのリスクが高まります。
タイムアウトの防止策
認証処理はアプリケーションの重要な部分であるため、タイムアウトを避けるために、ブロッキング関数にはミニマムインスタンスを設定することをお勧めします。
import { beforeUserCreated } from 'firebase-functions/v2/identity';
export const beforecreated = beforeUserCreated(
{
// ミニマムインスタンス数を1に設定
minInstances: 1,
},
(event) => {
// TODO
return;
}
);
この設定により、指定された数のインスタンスが常時稼働状態となり、起動時間がかかってタイムアウトが発生するリスクを軽減できます。
ただし、ミニマムインスタンスを設定した状態でも、ミニマムインスタンスで処理可能な総リクエスト数を超えるようなアクセス負荷が集中した場合は、新しいインスタンスが起動されるため、起動時間によるタイムアウトを100%防止できるわけではありません。
プロジェクトによってはミニマムインスタンス数をより多めに設定したほうが良い場合もありますので、要件に応じて適切なミニマムインスタンス数を設定しましょう。
コスト管理のための環境別設定
タイムアウト対策としてミニマムインスタンスを設定するのは有効ですが、インスタンスが常時稼働状態となるため、その分の費用も発生します。開発環境と本番環境でFirebaseプロジェクトを別々に管理している場合は、環境変数を利用し、本番環境のみにミニマムインスタンスを設定することも可能です。
ENVIRONMENT='production'
ENVIRONMENT='staging'
import { defineString } from 'firebase-functions/params';
import { beforeUserCreated } from 'firebase-functions/v2/identity';
export const beforecreated = beforeUserCreated(
{
// 環境変数ENVIRONMENTがproductionの場合のみミニマムインスタンス数に1を設定
minInstances: defineString('ENVIRONMENT').equals('production').thenElse(1, 0),
},
(event) => {
// TODO
return;
}
);
コストを抑えつつ本番環境でのトラブルを軽減できるので、開発環境でたまに発生する認証エラーが許容できる場合は、こちらの設定もお勧めです。