はじめに: 最初の関数を作成してデプロイする

Cloud Functions を使い始めるには、このチュートリアルを実践します。このチュートリアルは、必要な設定タスクから始まり、次の 2 つの関連する関数を作成してデプロイします。

  • addMessage() は、テキスト値を受け取る URL を公開し、そのテキスト値を Realtime Database に書き込みます。
  • makeUppercase() は、Realtime Database の書き込みでトリガーされ、テキストを大文字に変換します。

このサンプルでは Realtime Database および HTTP でトリガーされる関数を選択しましたが、関数をトリガーするオプションはさらに多くあります。入門ガイドで認証イベントアナリティクス イベントをご確認ください。

このチュートリアルの以下のセクションでは、サンプルをビルドおよびデプロイするために必要な手順について詳しく説明します。コードの実行と検査のみを行う場合は、完成したサンプルコードの確認に進んでください。

Node.js と Firebase CLI を設定する

関数を作成するには Node.js 環境が必要です。また、Cloud Functions ランタイムに関数をデプロイするには Firebase CLI が必要です(Node.js と npm も必要です)。

Cloud Functions は Node v6 または Node v8 のいずれかで実行できます。Node v6 で作成された関数がある場合は、そのバージョンを引き続き使用できます(デフォルトは v6 です)。詳しくは、ランタイム オプションの設定をご覧ください。

Node.js と npm をインストールする場合は、Node Version Manager をおすすめします。Node.js と npm をインストールしたら、npm を使用して Firebase CLI をインストールします。

npm install -g firebase-tools

これにより、グローバルに使用できる firebase コマンドがインストールされます。コマンドが失敗した場合は、npm アクセス権の変更が必要になる場合があります。firebase-tools の最新バージョンに更新するには、同じコマンドを再実行します。

Firebase SDK for Cloud Functions を初期化する

Firebase SDK for Cloud Functions を初期化するときに、依存関係と最小限のサンプルコードを含む空のプロジェクトを作成します。また、関数を作成するツールとして TypeScript か JavaScript のいずれかを選択します。

プロジェクトを初期化するには:

  1. firebase login を実行してブラウザからログインし、firebase ツールを認証します。
  2. Firebase プロジェクトのディレクトリに移動します。
  3. firebase init functions を実行します。このツールには、npm で依存関係をインストールするオプションがあります。依存関係を別の方法で管理する場合は、選択する必要はありません。
  4. このツールは、2 つの言語をサポートしています。

これらのコマンドが正常に完了すると、プロジェクト構造は次のようになります。

JavaScript

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

TypeScript

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
      |
      +- package.json  # npm package file describing your Cloud Functions code.
      |
      +- tsconfig.json # Config file containing compiler options.
      |
      +- tslint.json   # Optional file containing rules for TypeScript linting.
      |
      +- src/     # Directory containing TypeScript source
      |   |
      |   +- index.ts     # main source file for your Cloud Functions code
      |
      +- lib/
          |
          +- index.js     # JavaScript output from TypeScript source.
          |
          +- index.js.map # Sourcemap file for TypeScript source.

必要なモジュールをインポートしてアプリを初期化する

設定が完了したら、以降のセクションで説明するように、ソース ディレクトリを開いてコードを追加します。このサンプルでは、プロジェクトはノード require ステートメントを使用して Cloud Functions と Admin SDK モジュールをインポートする必要があります。index.js ファイルに次のような行を追加します。

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();

これらの行によって firebase-functions および firebase-admin モジュールがロードされ、Realtime Database の変更が可能な 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 the
// Realtime Database under the path /messages/:pushId/original
exports.addMessage = functions.https.onRequest((req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into the Realtime Database using the Firebase Admin SDK.
  return admin.database().ref('/messages').push({original: original}).then((snapshot) => {
    // Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console.
    return res.redirect(303, snapshot.ref.toString());
  });
});

addMessage() 関数は、HTTP エンドポイントです。エンドポイントに対するリクエストを行うと、Express.JS スタイルの Request オブジェクトと Response オブジェクトが onRequest() コールバックに渡されます。

呼び出し可能な関数と同様に HTTP 関数は同期的です。このため、できるだけ早くレスポンスを送信し、Realtime Database による作業を遅らせる必要があります。addMessage() HTTP 関数は、テキスト値を HTTP エンドポイントに渡し、事前に初期化された admin アプリを使用して /messages/:pushId/original パスの下で Realtime Database に挿入します。

addMessage() をデプロイして実行する

addMessage() 関数をデプロイして実行するには、次の手順に従います。

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

    $ firebase deploy --only functions
    

    このコマンドを実行すると、Firebase CLI は HTTP 関数のエンドポイントの URL を出力します。端末には、次のような行が表示されます。

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

    この URL には、プロジェクト ID と HTTP 関数のリージョンが含まれています。ここでは必要ありませんが、本番環境の HTTP 関数では、ネットワーク レイテンシを最小限に抑えるため、ロケーションの指定が必要になる場合があります。

  2. テキストクエリ パラメータを addMessage() URL に追加し、ブラウザで開きます。

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercaseme
    

    関数によりブラウザが実行され、テキスト文字列が格納されているデータベースの場所にある Firebase コンソールにリダイレクトされます。テキスト値がコンソールに表示されます。

関数をデプロイして実行した後、Firebase コンソールでログを表示できます。

makeUppercase() 関数を追加する

makeUppercase() 関数の場合、次の行を index.js に追加します。

// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();
      console.log('Uppercasing', context.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return snapshot.ref.parent.child('uppercase').set(uppercase);
    });

makeUppercase() 関数は、Realtime Database に書き込まれるときに実行されます。データベースでリッスンする対象を ref(path) 関数で定義します。パフォーマンス上の理由から、可能な限り具体的にする必要があります。

中かっこ({pushId} など)は、「パラメータ」を囲みます。これは、コールバックで一致したデータを公開するワイルドカードです。

Realtime Database は、指定されたパス上でデータの書き込みまたは更新が行われるたびに、onWrite() コールバックをトリガーします。

Realtime Database イベントなどのイベント駆動型の関数は非同期です。コールバック関数は、null、オブジェクト、Promise のいずれかを返す必要があります。何も返さない場合、関数はタイムアウトし、エラーを通知し、再試行されます。同期、非同期、Promise をご覧ください。

makeUppercase() をデプロイして実行する

チュートリアルを完了するには、関数を再度デプロイしてから addMessage() を実行して makeUppercase() をトリガーします。

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

    $ firebase deploy --only functions
    

    「プロジェクトへのアクセスを許可できません」などのアクセスエラーが発生した場合は、プロジェクト エイリアスを確認してみてください。

  2. CLI によって出力された addMessage() URL を使用して、テキスト クエリ パラメータを追加し、ブラウザで開きます。

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

    関数によりブラウザが実行され、テキスト文字列が格納されているデータベースの場所にある Firebase コンソールにリダイレクトされます。この書き込みイベントによって、大文字の文字列を書き込む makeUppercase() がトリガーされます。

関数をデプロイして実行した後、Cloud Functions の Firebase コンソールでログを表示できます。開発環境または本番環境で関数を削除する必要がある場合は、Firebase CLI を使用します。

完成したサンプルコードの確認

ここでは、関数 addMessage()makeUppercase() を含む完成した functions/index.js を示します。これらの関数を使用すると、Realtime Database に値を書き込み、文字列内のすべての文字を大文字にして変換する HTTP エンドポイントにパラメータを渡すことができます。

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into the
// Realtime Database under the path /messages/:pushId/original
exports.addMessage = functions.https.onRequest((req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into the Realtime Database using the Firebase Admin SDK.
  return admin.database().ref('/messages').push({original: original}).then((snapshot) => {
    // Redirect with 303 SEE OTHER to the URL of the pushed object in the Firebase console.
    return res.redirect(303, snapshot.ref.toString());
  });
});

// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();
      console.log('Uppercasing', context.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return snapshot.ref.parent.child('uppercase').set(uppercase);
    });

次のステップ

このドキュメントでは、Cloud Functions の一般的なコンセプトと、Cloud Functions でサポートされるイベントタイプを処理する関数の作成方法について説明しています。

Cloud Functions についてさらに学習するために、次のことを実践することもできます。

動画チュートリアル

Cloud Functions の詳細については、動画チュートリアルを参照してください。この動画では、Node.js や CLI の設定など、Cloud Functions を使い始めるための詳細なガイダンスをご覧いただけます。

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。