Cloud Functions を使用するにあたり、まずはこのチュートリアルを実践してください。このチュートリアルでは、必要な設定タスクから始め、次の 2 つの関連する関数の作成、テスト、デプロイを実践します。
- 「add message」関数は、テキスト値を受け取る URL を公開し、そのテキスト値を Cloud Firestore に書き込みます。
- 「make uppercase」関数は、Cloud Firestore の書き込みでトリガーされ、テキストを大文字に変換します。
このサンプルでは、Cloud Firestore と HTTP トリガー JavaScript 関数を選択しました。その理由の 1 つとしては、これらのバックグラウンド トリガーは Firebase Local Emulator Suite で十分にテストできるためです。このツールセットでは、Realtime Database、Pub/Sub、Auth、HTTP 呼び出し可能トリガーもサポートされています。このページでは説明されていませんが、Remote Config、TestLab、アナリティクスのトリガーなど、他の種類のバックグラウンド トリガーもすべて対応するツールセットを使用してインタラクティブにテストできます。
このチュートリアルの以下のセクションでは、サンプルをビルド、テスト、デプロイするために必要な手順について詳しく説明します。コードの実行と検査のみを行う場合は、完成したサンプルコードの確認に進んでください。
Firebase プロジェクトを作成する
-
Firebase コンソールで [プロジェクトを追加] をクリックします。
-
Firebase リソースを既存の Google Cloud プロジェクトに追加するには、そのプロジェクト名を入力するか、プルダウン メニューから選択します。
-
新しいプロジェクトを作成するには、任意のプロジェクト名を入力します。必要に応じて、プロジェクト名の下に表示されるプロジェクト ID を編集することもできます。
-
-
Firebase の利用規約が表示されたら、内容を読み、同意します。
-
[続行] をクリックします。
-
(省略可)プロジェクトに対し Google Analyticsを設定します。これにより、次の Firebase プロダクトを使用する際のエクスペリエンスを最適化できます。
既存の Google Analytics アカウントを選択するか、新しいアカウントを作成します。
新しいアカウントを作成する場合は、Analytics レポートのロケーションを選択し、プロジェクトのデータ共有設定と Google Analyticsの規約に同意します。
-
[プロジェクトを作成](既存の Google Cloud プロジェクトを使用する場合は [Firebase を追加])をクリックします。
Firebase プロジェクトのリソースが自動的にプロビジョニングされます。処理が完了すると、Firebase コンソールに Firebase プロジェクトの概要ページが表示されます。
Node.js と Firebase CLI を設定する
関数を作成するには Node.js 環境が必要です。また、Cloud Functions ランタイムに関数をデプロイするには Firebase CLI が必要です。Node.js と npm をインストールする場合は、Node Version Manager をおすすめします。
Node.js と npm をインストールしたら、お好みの方法を使用して Firebase をインストールします。npm を使用して CLI をインストールするには、次のコマンドを使用します。
npm install -g firebase-tools
これにより、グローバルに使用できる firebase コマンドがインストールされます。コマンドが失敗した場合は、npm アクセス権の変更が必要になる場合があります。firebase-tools
を最新バージョンに更新するには、同じコマンドを再実行します。
プロジェクトの初期化
Cloud Functions の Firebase SDK を初期化するときに、依存関係と最小限のサンプルコードを含む空のプロジェクトを作成します。また、関数を作成するツールとして TypeScript か JavaScript のいずれかを選択します。このチュートリアルでは、Cloud Firestore も初期化する必要があります。
プロジェクトを初期化するには:
firebase login
を実行してブラウザからログインし、Firebase を認証します。- Firebase プロジェクトのディレクトリに移動します。
firebase init firestore
を実行します。このチュートリアルでは、Firestore ルールとインデックス ファイルのプロンプトが表示されたら、デフォルト値をそのまま使用してかまいません。このプロジェクトでまだ Cloud Firestore を使用していない場合は、Cloud Firestore を使ってみるの説明に沿って、Firestore の開始モードとロケーションも選択する必要があります。firebase init functions
を実行します。既存のコードベースを選択するか、新しいコードベースを初期化して名前を付けるように求められます。最初は、デフォルトの場所にある単一のコードベースで十分です。後で実装を拡張する場合は、コードベースの関数を整理することをおすすめします。CLI は 2 つの言語をサポートしています。
- JavaScript
- TypeScript。詳細については、TypeScript での関数の作成をご覧ください。
このチュートリアルでは、JavaScript を選択します。
CLI には、npm で依存関係をインストールするオプションがあります。依存関係を別の方法で管理する場合は、このオプションを選択する必要はありません。ただし、選択しない場合でも、関数のエミュレートまたはデプロイの前に
npm install
を実行する必要があります。
これらのコマンドが正常に完了すると、プロジェクト構造は次のようになります。
myproject
+- .firebaserc # Hidden file that helps you quickly switch between
| # projects with `firebase use`
|
+- firebase.json # Describes properties for your project
|
+- functions/ # Directory containing all your functions code
|
+- .eslintrc.json # Optional file containing rules for JavaScript linting.
|
+- package.json # npm package file describing your Cloud Functions code
|
+- index.js # main source file for your Cloud Functions code
|
+- node_modules/ # directory where your dependencies (declared in
# package.json) are installed
初期化時に作成された package.json
ファイルには、重要なキー "engines": {"node": "16"}
が格納されています。これにより、関数の作成とデプロイ用の Node.js バージョンを指定します。他のサポート対象バージョンを選択することもできます。
必要なモジュールをインポートしてアプリを初期化する
設定が完了したら、以降のセクションで説明するように、ソース ディレクトリを開いてコードを追加します。このサンプルでは、プロジェクトはノード require
ステートメントを使用して Cloud Functions と Admin SDK モジュールをインポートする必要があります。index.js
ファイルに次のような行を追加します。
// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers. const functions = require('firebase-functions/v1'); // The Firebase Admin SDK to access Firestore. const admin = require("firebase-admin"); admin.initializeApp();
これらの行によって firebase-functions
モジュールおよび firebase-admin
モジュールが読み込まれ、Cloud Firestore の変更が可能な admin
アプリ インスタンスが初期化されます。Admin SDK サポートは FCM、Authentication、Firebase Realtime Database に対応しているため、これが利用可能な場所ではどこでも、Cloud Functions を使用して効果的に Firebase を統合できます。
Firebase CLI では、プロジェクトの初期化時に Firebase モジュールと Firebase SDK for Cloud Functions ノード モジュールが自動的にインストールされます。サードパーティ ライブラリをプロジェクトに追加するには、package.json
を変更して npm install
を実行します。
詳細については、依存関係の扱いをご覧ください。
addMessage()
関数を追加する
addMessage()
関数については、index.js
に次の行を追加します。
// Take the text parameter passed to this HTTP endpoint and insert it into // Firestore under the path /messages/:documentId/original exports.addMessage = functions.https.onRequest(async (req, res) => { // Grab the text parameter. const original = req.query.text; // Push the new message into Firestore using the Firebase Admin SDK. const writeResult = await admin .firestore() .collection("messages") .add({ original: original }); // Send back a message that we've successfully written the message res.json({ result: `Message with ID: ${writeResult.id} added.` }); });
addMessage()
関数は、HTTP エンドポイントです。エンドポイントに対するリクエストを行うと、Express.JS スタイルの Request オブジェクトと Response オブジェクトが onRequest()
コールバックに渡されます。
呼び出し可能な関数と同様に HTTP 関数は同期的です。このため、できるだけ早くレスポンスを送信し、Cloud Firestore による作業を遅らせる必要があります。addMessage()
HTTP 関数は、テキスト値を HTTP エンドポイントに渡し、/messages/:documentId/original
パスの下でデータベースに挿入します。
makeUppercase()
関数を追加する
makeUppercase()
関数については、index.js
に次の行を追加します。
// Listens for new messages added to /messages/:documentId/original and creates an // uppercase version of the message to /messages/:documentId/uppercase exports.makeUppercase = functions.firestore .document("/messages/{documentId}") .onCreate((snap, context) => { // Grab the current value of what was written to Firestore. const original = snap.data().original; // Access the parameter `{documentId}` with `context.params` functions.logger.log("Uppercasing", context.params.documentId, original); const uppercase = original.toUpperCase(); // You must return a Promise when performing asynchronous tasks inside a Functions such as // writing to Firestore. // Setting an 'uppercase' field in Firestore document returns a Promise. return snap.ref.set({ uppercase }, { merge: true }); });
makeUppercase()
関数は、Cloud Firestore に書き込まれるときに実行されます。ref.set
関数ではリッスン対象のドキュメントを定義します。パフォーマンス上の理由から、可能な限り具体的にする必要があります。
中かっこ({documentId}
など)は、「パラメータ」を囲みます。これは、コールバックで一致したデータを公開するワイルドカードです。
新しいメッセージが追加されるたびに、Cloud Firestore は onCreate()
コールバックをトリガーします。
Cloud Firestore イベントなどのイベント駆動型の関数は非同期です。コールバック関数は、null
、オブジェクト、Promise のいずれかを返す必要があります。何も返さない場合、関数はタイムアウトして、エラーを通知し、再試行されます。同期、非同期、Promise をご覧ください。
関数の実行をエミュレートする
Firebase Local Emulator Suite を使用すると、Firebase プロジェクトにデプロイする代わりにローカルマシンでアプリをビルドしてテストできます。開発中にローカルテストを行うことを強くおすすめします。その理由の 1 つとしては、本番環境でコストを発生させる可能性があるコーディング エラーのリスク(無限ループなど)が低下するためです。
関数をエミュレートするには:
firebase emulators:start
を実行し、Emulator Suite UI の URL の出力を確認します。デフォルトは localhost:4000 ですが、お使いのマシンによっては別のポートでホストされている場合があります。その URL をブラウザに入力して、Emulator Suite UI を開きます。firebase emulators:start
コマンドの出力で、HTTP 関数addMessage()
の URL を確認します。この URL は次のような形式です。http://localhost:5001/MY_PROJECT/us-central1/addMessage
。ただし:MY_PROJECT
はプロジェクト ID に置き換えられます。- お使いのローカルマシンによってはポートが異なる場合があります。
関数の URL の末尾にクエリ文字列
?text=uppercaseme
を追加します。http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme
のようになります。メッセージ「uppercaseme」をカスタム メッセージに変更することもできます。ブラウザの新しいタブで URL を開いて、新しいメッセージを作成します。
Emulator Suite UI で関数の動作を確認します。
[ログ] タブに、
addMessage()
関数とmakeUppercase()
関数が実行されたことを示す新しいログが表示されます。i functions: Beginning execution of "addMessage"
i functions: Beginning execution of "makeUppercase"
[Firestore] タブに、元のメッセージと大文字に変換されたメッセージを含むドキュメントが表示されます(元のメッセージが「uppercaseme」だった場合、変換後は「UPPERCASEME」となります)。
本番環境に関数をデプロイする
エミュレータで関数が意図したとおりに動作するようになったら、本番環境への関数のデプロイ、テスト、実行に進むことができます。推奨される Node.js 14 ランタイム環境にデプロイするには、プロジェクトが Blaze 料金プランを利用している必要がある点にご注意ください。Cloud Functions の料金をご覧ください。
チュートリアルを完了するには、関数をデプロイしてから addMessage()
を実行して makeUppercase()
をトリガーします。
次のコマンドを実行して、関数をデプロイします。
firebase deploy --only functions
このコマンドを実行すると、Firebase CLI は HTTP 関数のエンドポイントの URL を出力します。デバイスには、次のような行が表示されます。
Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
この URL には、プロジェクト ID と HTTP 関数のリージョンが含まれています。ここでは必要ありませんが、本番環境の HTTP 関数では、ネットワーク レイテンシを最小限に抑えるため、ロケーションの指定が必要になる場合があります。
「プロジェクトへのアクセスを許可できません」などのアクセスエラーが発生した場合は、プロジェクト エイリアスを確認してみてください。
CLI によって出力された
addMessage()
URL を使用して、テキスト クエリ パラメータを追加し、ブラウザで開きます。https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
関数によりブラウザが実行され、テキスト文字列が格納されているデータベースの場所にある Firebase コンソールにリダイレクトされます。この書き込みイベントによって、大文字の文字列を書き込む
makeUppercase()
がトリガーされます。
関数をデプロイして実行した後、Google Cloud コンソールでログを表示できます。開発環境または本番環境で関数を削除する必要がある場合は、Firebase CLI を使用します。
本番環境では、実行するインスタンスの最小数と最大数を設定して関数のパフォーマンスを最適化し、コストを抑えられます。これらのランタイム オプションの詳細については、スケーリング動作を制御するをご覧ください。
完成したサンプルコードの確認
ここでは、関数 addMessage()
と makeUppercase()
を含む完成した functions/index.js
を示します。これらの関数を使用すると、Cloud Firestore に値を書き込み、文字列内のすべての文字を大文字にして変換する HTTP エンドポイントにパラメータを渡すことができます。
// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers. const functions = require('firebase-functions/v1'); // The Firebase Admin SDK to access Firestore. const admin = require("firebase-admin"); admin.initializeApp(); // Take the text parameter passed to this HTTP endpoint and insert it into // Firestore under the path /messages/:documentId/original exports.addMessage = functions.https.onRequest(async (req, res) => { // Grab the text parameter. const original = req.query.text; // Push the new message into Firestore using the Firebase Admin SDK. const writeResult = await admin .firestore() .collection("messages") .add({ original: original }); // Send back a message that we've successfully written the message res.json({ result: `Message with ID: ${writeResult.id} added.` }); }); // Listens for new messages added to /messages/:documentId/original and creates an // uppercase version of the message to /messages/:documentId/uppercase exports.makeUppercase = functions.firestore .document("/messages/{documentId}") .onCreate((snap, context) => { // Grab the current value of what was written to Firestore. const original = snap.data().original; // Access the parameter `{documentId}` with `context.params` functions.logger.log("Uppercasing", context.params.documentId, original); const uppercase = original.toUpperCase(); // You must return a Promise when performing asynchronous tasks inside a Functions such as // writing to Firestore. // Setting an 'uppercase' field in Firestore document returns a Promise. return snap.ref.set({ uppercase }, { merge: true }); });
次のステップ
このドキュメントでは、Cloud Functions の関数の管理方法と、Cloud Functions でサポートされているすべてのイベントタイプを処理する方法について説明します。
Cloud Functions の詳細については、以下もご覧ください。
- Cloud Functions のユースケースを確認します。
- Cloud Functions Codelab を試す。
- GitHub のコードサンプルを確認して実行する