Firebase SDK for Cloud Functions アップグレード ガイド: ベータ版からバージョン 1.0 または 2.0 へのアップグレード

Firebase SDK for Cloud Functions のバージョン 1.0.0 では、API にいくつかの重要な変更が導入されています。特に重要な変更点として、event.data 形式が data および context パラメータに置き換えられており、これはすべての非同期(非 HTTP)関数に影響します。更新後の SDK は、新しい単体テスト コンパニオン SDK である firebase-functions-test でも使用できます。詳しくは、単体テストの関数をご覧ください。

Firebase SDK for Cloud Functions のバージョン 2.0.0 では、Firestore でトリガーされる関数のタイムスタンプに変更が行われました。この変更は互換性に対応していません。

SDK を最新バージョンに更新するには、関数フォルダで次のコマンドを実行します。

npm install firebase-functions@latest --save
npm install firebase-admin@latest --save-exact

Firebase CLI も最新バージョンに更新する必要があります。

npm install -g firebase-tools

すべての非同期(非 HTTP)関数に影響する SDK の変更点

SDK でのトリガーのタイプ別の変更点

新しい API リファレンスと従来の API リファレンス

関数のエミュレーションの変更

すべてのバックグラウンド(非 HTTP)関数に影響する SDK の変更点

data と context に分割された event パラメータ

Firebase SDK for Cloud Functions v 1.0 で、非同期関数用の event パラメータは廃止されます。このパラメータは、datacontext の 2 つの新しいパラメータに置き換えられました。

data パラメータは、関数をトリガーしたデータを表します。data パラメータのフィールドはトリガーのタイプによって決定され、またトリガーのタイプに応じて異なります。たとえば、Realtime Database の場合、data パラメータは DataSnapshot です。data パラメータの詳細については、トリガーのタイプ別の変更点をご覧ください。

context パラメータは、関数の実行に関する情報を提供します。非同期関数のタイプ全体で同じで、context には、eventIdtimestampeventTyperesourceparams の各フィールドが含まれます。さらに、Realtime Database 関数の場合は、関数をトリガーしたユーザーの認証情報も提供します。Realtime Database の書き込みによってトリガーされる関数で定義されている、コンテキスト フィールドの例を次に示します。

exports.dbWrite = functions.database.ref('/path/with/{id}').onWrite((data, context) => {
  const authVar = context.auth; // Auth information for the user.
  const authType = context.authType; // Permissions level for the user.
  const pathId = context.params.id; // The ID in the Path.
  const eventId = context.eventId; // A unique event ID.
  const timestamp = context.timestamp; // The timestamp at which the event happened.
  const eventType = context.eventType; // The type of the event that triggered this function.
  const resource = context.resource; // The resource which triggered the event.
  // ...
});

firebase-admin 用の新しい初期化構文

firebase-admin は、Cloud Functions ランタイム内でパラメータを使用せずに初期化されるようになりました。

以前(v0.9.1 以前)

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

現在(v1.0.0 以降)

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

初期化時には functions.config().firebase を渡すことができなくなりました。v1.0.0 で構成にアクセスする方法について詳しくは、次のセクションをご覧ください。

functions.config().firebase の削除

functions.config().firebase が削除されました。Firebase プロジェクトから構成値にアクセスする場合は、代わりに process.env.FIREBASE_CONFIG を使用します。

let firebaseConfig = JSON.parse(process.env.FIREBASE_CONFIG);
/* {  databaseURL: 'https://databaseName.firebaseio.com',
       storageBucket: 'projectId.appspot.com',
       projectId: 'projectId' }
*/

SDK でのトリガーのタイプ別の変更点

サポートされる多くの関数のトリガーに対して、v 1.0 ではデータ フィールドおよびメソッドの命名の変更が導入されています。このセクションでは、トリガーのタイプ別の変更点の一覧を示します。

Realtime Database

イベントデータが DataSnapshot に変更

以前のリリースでは、event.dataDeltaSnapshot でしたが、現在の v 1.0 では DataSnapshot です。

onWrite イベントと onUpdate イベントのデータ パラメータには before フィールドと after フィールドがあります。これらはそれぞれ DataSnapshot であり、admin.database.DataSnapshot で使用できるものと同じメソッドを持ちます。次に例を示します。

以前(v0.9.1 以前)

exports.dbWrite = functions.database.ref('/path').onWrite((event) => {
  const beforeData = event.data.previous.val(); // data before the write
  const afterData = event.data.val(); // data after the write
});

現在(v1.0.0 以降)

exports.dbWrite = functions.database.ref('/path').onWrite((change, context) => {
  const beforeData = change.before.val(); // data before the write
  const afterData = change.after.val(); // data after the write
});

onCreate の場合、データ パラメータは、追加されたばかりのデータを表す DataSnapshot です。

以前(v0.9.1 以前)

exports.dbCreate = functions.database.ref('/path').onCreate((event) => {
  const createdData = event.data.val(); // data that was created
});

現在(v1.0.0 以降)

exports.dbCreate = functions.database.ref('/path').onCreate((snap, context) => {
  const createdData = snap.val(); // data that was created
});

onDelete の場合、データ パラメータは、削除されたばかりのデータを表す DataSnapshot です。

以前(v0.9.1 以前)

exports.dbDelete = functions.database.ref('/path').onDelete((event) => {
  const deletedData = event.data.previous.val(); // data that was deleted
});

現在(v1.0.0 以降)

exports.dbDelete = functions.database.ref('/path').onDelete((snap, context) => {
  const deletedData = snap.val(); // data that was deleted
});

ユーザー認証情報用の新しいプロパティ

EventContext.auth V1.0.0 では、関数をトリガーしたユーザーに関する情報(権限など)にアクセスするために使用される 2 つのプロパティが新しく追加されました。

  • EventContext.authuid や認証済みユーザーの認証トークンなどの情報が含まれます。
  • EventContext.authType。権限レベルが含まれます。これにより、ユーザーが管理ユーザーかどうかといったことを検出できます。

文書化されていない event.auth フィールドを使用している場合、これらの新しいプロパティを使用するには関連するコードを更新する必要があります。

adminRefref に置換

.adminRef 参照が削除され、管理者権限で承認されるようになった .ref 参照に置き換えられました。.ref の以前の使用法、つまりユーザーによって承認された変更への参照(実際に変更をトリガーした参照)としての使用法は、サポートされなくなりました。

以前(v0.9.1 以前)

exports.dbCreate = functions.database.ref('/path/{uid}').onCreate((event) => {
  const parentRef = event.data.adminRef.parent; // The Database reference to the parent authorized with admin privileges.

  const parentRefAsUser = event.data.ref.parent; // The Database reference to the parent authorized as the user which triggered the change.
});

現在(v1.0.0 以降)

exports.dbCreate = functions.database.ref('/path/{uid}').onCreate((snap, context) => {
  const parentRef = snap.ref.parent; // The Database reference to the parent authorized with admin privileges
});

今後も Admin SDK を使用して、Realtime Database に対しユーザー承認済みの変更を実行できます。

const functions = require('firebase-functions');
const admin = require('firebase-admin');

exports.impersonateMakeUpperCase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snap, context) => {
      const appOptions = JSON.parse(process.env.FIREBASE_CONFIG);
      appOptions.databaseAuthVariableOverride = context.auth;
      const app = admin.initializeApp(appOptions, 'app');
      const uppercase = snap.val().toUpperCase();
      const ref = snap.ref.parent.child('uppercase');

      const deleteApp = () => app.delete().catch(() => null);

      return app.database().ref(ref).set(uppercase).then(res => {
        // Deleting the app is necessary for preventing concurrency leaks
        return deleteApp().then(() => res);
      }).catch(err => {
        return deleteApp().then(() => Promise.reject(err));
      });
    });

Cloud Firestore

v 1.0 に関する Realtime Database の変更とほぼ同様に、onWriteonUpdate には before フィールドと after フィールドが含まれるデータ パラメータがあります。onCreateonDelete 両方のイベントには、Cloud Firestore の DocumentSnapshot であるデータ パラメータがあります。

以前(v0.9.1 以前)

exports.dbWrite = functions.firestore.document('/doc/path').onWrite((event) => {
  const beforeData = event.data.previous.data(); // data before the write
  const afterData = event.data.data(); // data after the write
});

現在(v1.0.0 以降)

exports.dbWrite = functions.firestore.document('/doc/path').onWrite((change, context) => {
  const beforeData = change.before.data(); // data before the write
  const afterData = change.after.data(); // data after the write
});

onCreateonDelete の両イベントには、DocumentSnapshot であるデータ パラメータがあります。

以前(v0.9.1 以前)

exports.dbDelete = functions.firestore.document('/doc/path').onDelete((event) => {
  const deletedData = event.data.previous.data(); // data that was deleted
});

現在(v1.0.0 以降)

exports.dbDelete = functions.firestore.document('/doc/path').onDelete((snap, context) => {
  const deletedData = snap.data(); // data that was deleted
});

v2.0.0 での Firestore タイムスタンプの大幅な変更

Firebase SDK for Cloud Functions の v2.0.0 では、関数内で受け取る Firestore スナップショットのタイムスタンプ値は、Firestore タイムスタンプ オブジェクトになります。これは、snapshot.createTimesnapshot.updateTimesnapshot.readTimesnapshot.data() のタイムスタンプ値に適用されます。

現在(v2.0.0 以降)

exports.dbCreate = functions.firestore.document('/doc/path').onCreate((snap, context) => {
  //seconds of UTC time since Unix epoch
  console.log(snap.createTime.seconds);

  //fractions of a second at nanosecond resolution, 0 to 999,999,999
  console.log(snap.createTime.nanoseconds);
});

Authentication

以前のリリースでは、event.data.metadata には非推奨フィールド createdAtlastSignedInAt が含まれていました。バージョン 1.0 ではこれらのフィールドが完全に削除され、creationTime パラメータの lastSignInTime フィールドと userRecord.metadata フィールドに置き換えられています。

以前(v0.9.1 以前)

// This code won't work with Cloud Functions SDK 1.0 and higher!
exports.authAction = functions.auth.user().onCreate((event) => {
  const userMetadata = event.data.metadata;

  const creationTime = userMetadata.createdAt; // 2016-12-15T19:37:37.059Z
  const lastSignInTime = userMetadata.lastSignedInAt; // 2018-01-03T16:23:12.051Z
}

現在(v1.0.0 以降)

exports.authAction = functions.auth.user().onCreate((userRecord, context) => {
  const creationTime = userRecord.metadata.creationTime; // 2016-12-15T19:37:37.059Z
  const lastSignInTime = userRecord.metadata.lastSignInTime; // 2018-01-03T16:23:12.051Z
}

Crashlytics

v 1.0 では、新しい問題が生じるたびに発生するイベント ハンドラは onNew です。onNewDetected という名前の以前のハンドラは削除されました。

以前(v0.9.1 以前)

exports.newIssue = functions.crashlytics.issue().onNewDetected((event) => {
  const issue = event.data;

  const issueId = issue.issueId;
  const issueTitle = issue.issueTitle;
  const appName = issue.appInfo.appName;
  const appId = issue.appInfo.appId;
  const appPlatform = issue.appInfo.appPlatform;
  const latestAppVersion = issue.appInfo.latestAppVersion;
  const createTime = issue.createTime;
}

現在(v1.0.0 以降)

exports.newIssue = functions.crashlytics.issue().onNew((issue, context) => {
  const issueId = issue.issueId;
  const issueTitle = issue.issueTitle;
  const appName = issue.appInfo.appName;
  const appId = issue.appInfo.appId;
  const appPlatform = issue.appInfo.appPlatform;
  const latestAppVersion = issue.appInfo.latestAppVersion;
  const createTime = issue.createTime;
}

Storage

onChange イベント ハンドラが削除されました。代わりに、v 1.0 では次のイベントをサポートします。

  • onArchive。バケットでオブジェクトのバージョニングが有効になっている場合にのみ送信されます。このイベントは、アーカイブまたは同じ名前のオブジェクトのアップロードにより、オブジェクトのライブ バージョンがアーカイブ バージョンになったことを表します。
  • onDelete。オブジェクトが完全に削除された場合に送信されます。バケットのライフサイクル構成で上書きまたは削除されたオブジェクトも対象になります。オブジェクトのバージョニングが有効になっているバケットの場合、オブジェクトがアーカイブされたときに、このイベントは送信されません(onArchive を参照)。storage.objects.delete メソッドでアーカイブが発生した場合も同様です。
  • onFinalize。バケットで新しいオブジェクト(または既存オブジェクトの新しい世代)が正常に作成された場合に送信されます。既存のオブジェクトをコピーまたは再作成した場合にも送信されます。アップロードが失敗した場合、このイベントはトリガーされません。
  • onMetadataUpdate。既存オブジェクトのメタデータが変更された場合に送信されます。

以前(v0.9.1 以前)

exports.processFile = functions.storage.object().onChange((event) => {
  const object = event.data;

  const filePath = object.name; // Path of the File
  const contentType = object.contentType; // Mime type of the file

  // Exit if this is a deletion event.
  if (object.resourceState === 'not_exists') {
    console.log('This file was deleted.');
    return null;
  }

  // Exit if file exists but is not new and is only being triggered
  // because of a metadata change.
  if (resourceState === 'exists' && metageneration > 1) {
    console.log('This is a metadata change event.');
    return null;
  }

  // ...
}

現在(v1.0.0 以降)

exports.processFile = functions.storage.object().onFinalize((object, context) => {
  const filePath = object.name; // Path of the File
  const contentType = object.contentType; // Mime type of the file

  // ...
}

exports.fileDeleted = functions.storage.object().onDelete((object, context) => {
  console.log('This file was deleted.');
}

exports.metadataUpdated = functions.storage.object().onMetadataUpdate((object, context) => {
  console.log('This is a metadata change event.');
}

Pub/Sub

基礎となるトリガータイプが変更されたため、Pub/Sub 関数の名前を変更して再デプロイする必要があります。関数のコードを変更する必要はありません。

Pub/Sub 関数を更新するには:

  1. 関数の名前を変更します。たとえば、「myPubSubFunction」を「myNewPubSubFunction」に変更します。
  2. 部分デプロイを使用して、その関数のみをデプロイします。

    firebase deploy --only functions:myNewPubSubFunction

  3. 「myNewPubSubFunction」が正常にデプロイされたら、すべての関数をデプロイして、v.1.0.0 以前の古い関数を削除します。

    firebase deploy --only functions

これらのデプロイ コマンドの間の短時間に、重複したトリガーを受信することがあります。この現象を処理して正常に動作させるためには、べき等関数を作成してください。

新しい API リファレンスと従来の API リファレンス

詳細については、firebase-functions v1.0.0 の API リファレンスをご覧ください。また、v0.9.1 の API リファレンスを参照すると、アップグレードに役立ちます。

関数のエミュレーションの変更

  • firebase serve が HTTP 関数とホスティングの両方にデフォルトで対応するようになりました。
  • すべての関数をエミュレートする firebase experimental:functions:shell の名前が firebase functions:shell に変更されました。

Functions シェルの構文の変更

Functions シェルで関数を呼び出すための構文が、firebase-functions v1.0.0 の構文を反映して更新されました。

// Inside functions shell

// To emulate database writes done by an administrative user:
myDbFunction(‘data’)

// To emulate database writes done by an authenticated user:
myDbFunction(‘data’, { auth: { uid: ‘abc’ }})

// To emulate database writes done by an unauthenticated user:
myDbFunction(‘data’, { authMode: ‘UNAUTHENTICATED’)

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

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