Firebase Summit で発表されたすべての情報をご覧ください。Firebase を使用してアプリ開発を加速し、自信を持ってアプリを実行する方法を紹介しています。詳細

機能の管理

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

Firebase CLI コマンドを使用するか、関数のソース コードでランタイム オプションを設定することにより、関数をデプロイ、削除、および変更できます。

関数をデプロイする

関数をデプロイするには、次の Firebase CLI コマンドを実行します。

$ firebase deploy --only functions

デフォルトでは、Firebase CLI はindex.js内のすべての関数を同時にデプロイします。プロジェクトに 5 つ以上の関数が含まれている場合は、特定の関数名で--onlyフラグを使用して、編集した関数のみをデプロイすることをお勧めします。この方法で特定の機能をデプロイすると、デプロイ プロセスが高速化され、デプロイ クォータに達するのを回避するのに役立ちます。例えば:

$ firebase deploy --only functions:addMessage,functions:makeUppercase

多数の関数をデプロイすると、標準のクォータを超えて、HTTP 429 または 500 エラー メッセージが表示される場合があります。これを解決するには、関数を 10 個以下のグループでデプロイします。

使用可能なコマンドの完全なリストについては、 Firebase CLI リファレンスを参照してください。

デフォルトでは、Firebase CLI はfunctions/フォルダーでソース コードを検索します。必要に応じて、コードベースまたは複数のファイル セットで関数を整理できます。

関数の削除

次の方法で、以前にデプロイされた関数を削除できます。

  • 関数を使用して Firebase CLI で明示的functions:delete
  • Firebase コンソールの関数リストでコンテキスト メニューを明示的に使用する
  • 展開前にindex.jsから関数を削除することにより、暗黙的に。

すべての削除操作では、本番環境から関数を削除する前に確認を求めるプロンプトが表示されます。

Firebase CLI での明示的な関数の削除は、複数の引数と関数グループをサポートし、特定のリージョンで実行されている関数を指定できるようにします。また、確認プロンプトを上書きすることもできます。

# Delete all functions that match the specified name in all regions.
$ firebase functions:delete myfunction

# Delete a specified function running in a specific region.
$ firebase functions:delete myfunction --region us-east-1

# Delete more than one function
$ firebase functions:delete myfunction myotherfunction

# Delete a specified functions group.
$ firebase functions:delete groupA

# Bypass the confirmation prompt.
$ firebase functions:delete myfunction --force

暗黙的な関数の削除により、 firebase deployindex.jsを解析し、ファイルから削除されたすべての関数を本番環境から削除します。

関数の名前、リージョン、またはトリガーを変更する

本番トラフィックを処理している関数のリージョンまたはトリガーの名前を変更または変更する場合は、このセクションの手順に従って、変更中にイベントが失われないようにしてください。これらの手順を実行する前に、まず関数がべきであることを確認してください。これは、関数の新しいバージョンと古いバージョンの両方が変更中に同時に実行されるためです。

関数の名前を変更する

関数の名前を変更するには、名前を変更した関数の新しいバージョンをindex.jsで作成し、2 つの個別のデプロイ コマンドを実行します。最初のコマンドは、新しく名前が付けられた関数をデプロイし、2 番目のコマンドは、以前にデプロイされたバージョンを削除します。たとえば、 webhookNewに変更したいwebhookという関数がある場合は、次のようにコードを修正します。

// before
const {onRequest} = require('firebase-functions/v2/https');

exports.webhook = onRequest((req, res) => {
    res.send("Hello");
});

// after
const {onRequest} = require('firebase-functions/v2/https');

exports.webhooknew = onRequest((req, res) => {
    res.send("Hello");
});

次に、次のコマンドを実行して、新しい関数をデプロイします。

# Deploy new function called webhookNew
$ firebase deploy --only functions:webhooknew

# Wait until deployment is done; now both webhooknew and webhook are running

# Delete webhook
$ firebase functions:delete webhook

関数のリージョンを変更する

本番トラフィックを処理する関数の指定されたリージョンを変更する場合は、次の手順を順番に実行することでイベントの損失を防ぐことができます。

  1. 関数の名前を変更し、必要に応じてその領域を変更します。
  2. 名前を変更した関数をデプロイします。これにより、両方のリージョン セットで同じコードが一時的に実行されます。
  3. 前の関数を削除します。

たとえば、現在us-central1のデフォルト関数リージョンにあるwebhookという関数があり、それをasia-northeast1に移行する場合、まずソース コードを変更して関数の名前を変更し、リージョンを修正する必要があります。 .

// before
const {onRequest} = require('firebase-functions/v2/https');

exports.webhook = onRequest((req, res) => {
    res.send("Hello");
});

// after
const {onRequest} = require('firebase-functions/v2/https');

exports.webhookasia = onRequest({
        region: 'asia-northeast1'
    }, (req, res) => {
    res.send("Hello");
});

次に、次を実行してデプロイします。

$ firebase deploy --only functions:webhookAsia

現在、2 つの同一の関数が実行されていますwebhookus-central1で実行され、 webhookasiaasia-northeast1で実行されています。

次に、 webhookを削除します。

$ firebase functions:delete webhook

現在、 asia-northeast1で実行されているwebhookasiaという関数が 1 つだけあります。

関数のトリガー タイプを変更する

時間をかけて Cloud Functions for Firebase デプロイメントを開発すると、さまざまな理由で関数のトリガー タイプの変更が必要になる場合があります。たとえば、あるタイプの Firebase Realtime Database または Cloud Firestore イベントを、汎用のonWriteイベントから詳細なonCreateイベントに変更するなど、別のタイプに変更したい場合があります。

ソース コードを変更してfirebase deployを実行するだけでは、関数のイベント タイプを変更することはできません。エラーを回避するには、次の手順で関数のトリガー タイプを変更します。

  1. ソース コードを変更して、目的のトリガー タイプを持つ新しい関数を含めます。
  2. 関数をデプロイします。これにより、古い関数と新しい関数の両方が一時的に実行されます。
  3. Firebase CLI を使用して、本番環境から古い関数を明示的に削除します。

たとえば、従来のonMetadataUpdatedイベント タイプを持つ関数objectchangedがあり、それをonObjectFinalizedに変更したい場合は、最初に関数の名前を変更し、編集してonObjectFinalizedイベント タイプを持つようにします。

// before
const {onMetadataUpdated} = require('firebase-functions/v2/storage');

exports.objectchanged = onMetadataUpdated((event) => {
    return console.log('File name is: ', event.data.name);
});

// after
const {onObjectFinalized} = require('firebase-functions/v2/storage');

exports.objectchanged = onObjectFinalized((event) => {
    return console.log('File name is: ', event.data.name);
});

次に、古い関数を削除する前に、まず次のコマンドを実行して新しい関数を作成します。

# Create new function objectFinalized
$ firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
$ firebase functions:delete objectChanged

ランタイム オプションの設定

Cloud Functions for Firebase では、Node.js ランタイム バージョン、関数ごとのタイムアウト、メモリ割り当て、最小/最大関数インスタンスなどのランタイム オプションを選択できます。

ベスト プラクティスとして、これらのオプション (Node.js バージョンを除く) は、関数コード内の構成オブジェクトで設定する必要があります。このRuntimeOptionsオブジェクトは、関数のランタイム オプションの信頼できる情報源であり、他の方法 (Google Cloud コンソールや gcloud CLI など) で設定されたオプションをオーバーライドします。

開発ワークフローで、Google Cloud コンソールまたは gcloud CLI を使用してランタイム オプションを手動で設定する必要があり、デプロイごとにこれらの値をオーバーライドしたくない場合は、 preserveExternalChangesオプションをtrueに設定します。このオプションをtrueに設定すると、Firebase は、コードに設定されたランタイム オプションを、現在デプロイされている関数のバージョンの設定と次の優先度でマージします。

  1. オプションは関数コードで設定されます: 外部の変更をオーバーライドします。
  2. 関数コードでオプションがRESET_VALUEに設定されています。外部の変更をデフォルト値で上書きします。
  3. オプションは関数コードでは設定されていませんが、現在デプロイされている関数で設定されています: デプロイされた関数で指定されたオプションを使用してください。

preserveExternalChanges: trueオプションを使用することは、ほとんどのシナリオでは推奨されません。これは、コードが関数のランタイム オプションの完全な情報源でなくなるためです。使用する場合は、Google Cloud コンソールを確認するか、gcloud CLI を使用して関数の完全な構成を表示します。

Node.js のバージョンを設定する

Firebase SDK for Cloud Functions (第 2 世代) では、Node.js ランタイムを選択できます。サポートされている Node.js バージョンのいずれかに対応するランタイム環境で、プロジェクト内のすべての関数を排他的に実行することを選択できます。

  • Node.js 16
  • Node.js 14

Node.js のバージョンを設定するには:

初期化中にfunctions/ディレクトリに作成されたpackage.jsonファイルのenginesフィールドにバージョンを設定します。たとえば、バージョン 16 のみを使用するには、 package.jsonで次の行を編集します。

  "engines": {"node": "16"}

enginesフィールドは必須です。関数をデプロイして実行するには、サポートされている Node.js バージョンのいずれかを指定する必要があります。現在、 firebase init functionsはこのフィールドを16に設定しています。

Node.js ランタイムをアップグレードする

Node.js ランタイムをアップグレードするには:

  1. プロジェクトがBlaze 料金プランに含まれていることを確認してください。
  2. Firebase CLI v9.17.0 以降を使用していることを確認してください。
  3. 初期化中にfunctions/ディレクトリに作成されたpackage.jsonファイルのengines値を変更します。たとえば、バージョン 10 からバージョン 16 にアップグレードする場合、エントリは次のようになります: "engines": {"node": "16"}
  4. Firebase CLI v9.17.0 以降を使用して関数を再デプロイします。

スケーリング動作の制御

デフォルトでは、Cloud Functions for Firebase は受信リクエストの数に基づいて実行中のインスタンスの数をスケーリングし、トラフィックが減少したときにゼロ インスタンスにスケールダウンする可能性があります。ただし、アプリで待機時間を短縮する必要があり、コールド スタートの回数を制限したい場合は、コンテナー インスタンスの最小数を指定してウォーム状態を維持し、要求を処理する準備を整えることで、この既定の動作を変更できます。

同様に、受信リクエストに応じてインスタンスのスケーリングを制限する最大数を設定できます。この設定を使用して、コストを制御したり、データベースなどのバッキング サービスへの接続数を制限したりします。

これらの設定をインスタンスごとの同時実行設定 (第 2 世代の新機能) と一緒に使用すると、関数のスケーリング動作を制御および調整できます。アプリケーションと機能の性質によって、どの設定が最も費用対効果が高く、最高のパフォーマンスが得られるかが決まります。

トラフィックが少ない一部のアプリでは、マルチコンカレンシーを使用しない低 CPU オプションが最適です。コールド スタートが重大な問題であるその他の場合、高い同時実行数と最小限のインスタンスを設定することは、トラフィックの大きなスパイクを処理するために一連のインスタンスが常にウォーム状態に保たれることを意味します。

トラフィックが非常に少ない小規模なアプリの場合、最大インスタンス数を低く設定して同時実行性を高めることは、アプリが過度のコストを発生させることなくトラフィックのバーストを処理できることを意味します。

同時リクエストを許可する

Cloud Functions for Firebase (第 1 世代) では、各インスタンスが一度に 1 つのリクエストを処理できるため、スケーリング動作はminInstancesmaxInstancesの設定のみで設定されていました。インスタンス数の制御に加えて、Cloud Functions for Firebase (第 2 世代) では、 concurrencyオプションを使用して、各インスタンスが同時に処理できるリクエストの数を制御できます。同時実行数のデフォルト値は 80 ですが、1 から 1000 までの任意の整数に設定できます。

各インスタンスにはある程度の余裕がある可能性が高いため、同時実行数の設定が高い関数は、コールド スタートせずにトラフィックのスパイクを吸収できます。インスタンスが最大 50 の同時リクエストを処理するように構成されているが、現在 25 しか処理していない場合、新しいインスタンスをコールド スタートすることなく、25 の追加リクエストのスパイクを処理できます。対照的に、同時実行数を 1 に設定した場合、要求が急増すると、25 回のコールド スタートが発生する可能性があります。

Cloud Functions for Firebase (第 2 世代) でより高い同時実行設定を試す場合は、次の点に注意してください。

  • 同時実行数を高く設定すると、実際の限界に達するまで、最適なパフォーマンスを得るために、より高い CPU と RAM が必要になる場合があります。たとえば、重い画像やビデオの処理を行う関数では、CPU と RAM の設定が最大化されている場合でも、1000 の同時要求を処理するためのリソースが不足している可能性があります。
  • Cloud Functions for Firebase (第 2 世代) は Cloud Run を利用しているため、同時実行の最適化に関する Google Cloud ガイダンスも参照できます。
  • 本番環境でマルチコンカレンシーに切り替える前に、テスト環境でマルチコンカレンシーを十分にテストしてください。

コールドスタートの回数を減らす

ソース コードで関数のインスタンスの最小数を設定するには、 minInstancesオプションを使用します。たとえば、次の関数は、ウォーム状態を保つために最小 5 つのインスタンスを設定します。

  const { onCall } = require("firebase-functions/v2/https");

  exports.getAutocompleteResponse = onCall(
    {
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    },
    (event) => {
      // Autocomplete user’s search term
    }
  );

minInstancesの値を設定する際には、次の点を考慮してください。

  • Cloud Functions for Firebase がminInstances設定を超えてアプリをスケーリングすると、そのしきい値を超えるインスタンスごとにコールド スタートが発生します。
  • コールド スタートは、トラフィックが急増するアプリに最も深刻な影響を与えます。アプリにスパイク トラフィックがあり、トラフィックが増加するたびにコールド スタートが減少するようにminInstances値を十分に高く設定すると、レイテンシが大幅に短縮されます。トラフィックが一定しているアプリの場合、コールド スタートがパフォーマンスに深刻な影響を与える可能性はほとんどありません。
  • 最小限のインスタンスを設定することは、本番環境では意味がありますが、通常、テスト環境では避けるべきです。テスト プロジェクトでゼロにスケールし、本番プロジェクトでのコールド スタートを減らすには、 FIREBASE_CONFIG環境変数に基づいてminInstancesを設定できます。

    // Get Firebase project ID from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = onRequest(
      {
        // Keep 5 instances warm for this latency-critical function
        // in production only. Default to 0 for test projects.
        minInstances: envProjectId === "my-production-project" ? 5 : 0,
      },
      (req, res) => {
        // render some html
      }
    );
    

関数のインスタンスの最大数を制限する

関数のソース コードで最大インスタンスを設定するには、 maxInstancesオプションを使用します。たとえば、次の関数は、仮想のレガシー データベースを圧倒しないように、100 インスタンスの制限を設定します。

  const { onMessagePublished } = require("firebase-functions/v2/pubsub");

  exports.mirrorevents = onMessagePublished(
    { topic: "topic-name", maxInstances: 100 },
    (event) => {
      // Connect to legacy database
    }
  );

HTTP 関数がmaxInstances制限までスケールアップされた場合、新しいリクエストは 30 秒間キューに入れられ、それまでに使用可能なインスタンスがない場合、 429 Too Many Requestsの応答コードで拒否されます。

最大インスタンス設定を使用するためのベスト プラクティスの詳細については、 maxInstancesを使用するためのこれらのベスト プラクティスを確認してください。

タイムアウトとメモリ割り当てを設定する

場合によっては、関数に長いタイムアウト値または大規模なメモリ割り当てに関する特別な要件がある場合があります。これらの値は、Google Cloud Console または関数のソース コード (Firebase のみ) で設定できます。

関数のソース コードでメモリ割り当てとタイムアウトを設定するには、 GlobalOptions.memoryGlobalOptions.timeoutSecondsを使用して、関数を実行する仮想マシンをカスタマイズします。たとえば、次の Cloud Storage 関数は 1 GiB のメモリを使用し、300 秒後にタイムアウトします。

  exports.convertLargeFile = onObjectFinalized({
    timeoutSeconds: 300,
    memory: "1GiB",
  }, (event) => {
    // Do some complicated things that take a lot of memory and time
  });

timeoutSecondsの最大値は540または 9 分です。

Google Cloud Console でメモリ割り当てとタイムアウトを設定するには:

  1. Google Cloud Console で、左側のメニューからCloud Functions for Firebaseを選択します。
  2. 関数リストで名前をクリックして、関数を選択します。
  3. トップメニューの編集アイコンをクリックします。
  4. [割り当てられたメモリ] というラベルの付いたドロップダウン メニューからメモリ割り当てを選択します。
  5. [詳細] をクリックして詳細オプションを表示し、[タイムアウト]テキスト ボックスに秒数を入力します。
  6. [保存]をクリックして関数を更新します。

CPU のデフォルトを上書きする

最大 2 GB のメモリが割り当てられます。Cloud Functions for Firebase (第 2 世代) の各関数はデフォルトで 1 つの CPU に設定され、その後 4 GB と 8 GB では 2 CPU に増加します。これは、次の表に示すように、低メモリ関数のコストがわずかに高くなる可能性があるという点で、第 1 世代の既定の動作とは大きく異なることに注意してください。

割り当てられた RAMバージョン 1 のデフォルト CPU (フラクショナル)バージョン 2 デフォルト CPUミリ秒あたりの価格上昇
128MB 1/12 1 10.5倍
256MB 1/6 1 5.3倍
512MB 1/3 1 2.7倍
1GB 7/12 1 1.6倍
2GB 1 1 1x
4ギガバイト2 2 1x
8GB 2 2 1x
16ギガバイトなし4なし

第 2 世代関数の第 1 世代の動作を維持したい場合は、グローバル オプションとして第 1 世代のデフォルトを設定します。

// Turn off Firebase defaults
setGlobalOptions({ cpu: 'gcfv1' });

CPU を集中的に使用する機能の場合、第 2 世代は追加の CPU を構成する柔軟性を提供します。次のように、関数ごとに CPU をブーストできます。

// Boost CPU in a function:
export const analyzeImage = onObjectFinalized({ cpu: 2 }, (event) => {
  // computer vision goes here
});