はじめに: 最初の関数の記述とデプロイ

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

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

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

Firebase プロジェクトでのサンプルのビルド

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

Firebase SDK for Cloud Functions の設定と初期化

最初に、Firebase CLI リファレンスで説明されているように、Firebase CLI をインストールします。Firebase CLI には Node.jsnpm が必要であり、これらは https://nodejs.org/ の指示に沿ってインストールできます。Node.js をインストールすると、npm もインストールされます。

Cloud Functions は Node v.6.11.5 を実行するので、このバージョンでローカルに開発することをおすすめします。

Node.js と npm をインストールしたら、npm を使用して Firebase CLI をインストールします。

npm install -g firebase-tools

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

プロジェクトを初期化する手順は次のとおりです。

  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(functions.config().firebase);

これらの行によって firebase-functions および firebase-admin モジュールがロードされ、Realtime Database の変更が可能な admin アプリ インスタンスが初期化されます。Admin SDK は FCM、Authentication、Firebase Realtime Database に対応しているため、これが利用可能な場所ではどこでも、Cloud Functions を使用して効果的に Firebase を統合することができます。

Firebase CLI では、プロジェクトの初期化時に Fireworks および Firebase SDK for Cloud Functions ノード モジュールが自動的にインストールされます。サードパーティ ライブラリをプロジェクトに追加するには、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);
  });
});

addMessage() 関数は、HTTP エンドポイントです。エンドポイントへのリクエストによって、ExpressJS スタイルの Request および Response オブジェクトが onRequest() コールバックに渡されます。

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

addMessage() のデプロイと実行

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

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

    $ firebase deploy --only functions
    

    デフォルトでは、Firebase CLI によって index.js 内のすべての関数が同時にデプロイされます。そのファイルに多数の関数が含まれていて、その一部だけをデプロイする必要がある場合は、--only 引数を使用して部分デプロイを実行します。

    $ firebase deploy --only functions:addMessage
    

    デプロイ後、Firebase CLI によって HTTP 関数のエンドポイントの URL が出力されます。端末には、次のような行が表示されます。

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

    デフォルトでは、Firebase CLI によって functions/ フォルダ内でソースコードが検索されます。firebase.json に次の行を追加して、別のフォルダを指定できます。

    "functions": {
      "source": "another-folder"
    }
    
  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').onWrite((event) => {
  // Grab the current value of what was written to the Realtime Database.
  const original = event.data.val();
  console.log('Uppercasing', event.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 event.data.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
    

    デフォルトでは、Firebase CLI によって functions/ フォルダ内でソースコードが検索されます。firebase.json に次の行を追加して、別のフォルダを指定できます。

    "functions": {
      "source": "another-folder"
    }
    

    「Unable to authorize access to project」などのアクセスエラーが発生した場合は、プロジェクト エイリアスを確認してみてください。

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

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

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

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

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

ここでは、関数 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(functions.config().firebase);

// 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);
  });
});

// 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').onWrite((event) => {
  // Grab the current value of what was written to the Realtime Database.
  const original = event.data.val();
  console.log('Uppercasing', event.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 event.data.ref.parent.child('uppercase').set(uppercase);
});

次のステップ

このドキュメントでは、Cloud Functions の一般的な概念の詳細と、Cloud Functions でサポートされるイベントタイプを処理する関数を記述するためのガイドを示しています。

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

動画チュートリアル

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

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

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