Firebase SDK for Cloud Functions-Upgrade-Leitfaden: Beta auf Version 1.0 oder höher

In Version 1.0.0 des Firebase SDK for Cloud Functions wurden einige wichtige Änderungen in der API eingeführt. Die primäre Veränderung, eine Ersetzung von event.data Format mit data und context betrifft alle asynchronen (Nicht-HTTP) Funktionen. Das aktualisierte SDK kann auch verwendet werden mit firebase-functions-test , einer Unit - Tests Begleiter SDK. Siehe Unit Testing - Funktionen für weitere Informationen.

Version 2.0.0 des Firebase SDK für Cloud - Funktionen eingeführt , um eine Änderung von Breaking für Zeitstempel in Firestor ausgelöste Funktionen .

Um SDKs auf die neueste Version zu aktualisieren, führen Sie im Funktionsordner Folgendes aus:

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

Sie sollten auch Firebase CLI auf die neueste Version aktualisieren:

npm install -g firebase-tools

SDK-Änderungen, die sich auf alle asynchronen (Nicht-HTTP-)Funktionen auswirken

SDK-Änderungen nach Triggertyp

Änderungen an der Funktionsemulation

SDK-Änderungen, die sich auf alle Hintergrundfunktionen (nicht HTTP) auswirken

Ereignisparameter aufgeteilt in Daten und Kontext

Ab v 1.0 des Firebase SDK für Cloud - Funktionen, das event ist Parameter für asynchrone Funktionen überflüssig. : Es wurde durch zwei neue Parameter ersetzt data und context .

Die data Parameter stellt die Daten, die die Funktion ausgelöst. Die Felder des data werden vom Triggertyp bestimmt und variieren entsprechend. Zum Beispiel für Echtzeit - Datenbank, die data sind Parameter ein DataSnapshot . Siehe Änderungen von Trigger - data Typ für weitere Informationen über die data - Parameter.

Der context Parameter informiert über die Ausführung der Funktion. Identische für asynchrone Funktionen Typen context enthält die Felder eventId , timestamp , eventType , resource und params . Darüber hinaus stellen Echtzeitdatenbankfunktionen Authentifizierungsinformationen für den Benutzer bereit, der die Funktion ausgelöst hat. Hier ist ein Beispiel für Kontextfelder, die in einer Funktion definiert sind, die durch einen Schreibvorgang in die Echtzeitdatenbank ausgelöst wird:

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

Neue Initialisierung Syntax für firebase-admin

firebase-admin jetzt ohne Parameter initialisiert wird innerhalb der Cloud - Funktionen Runtime.

Vorher (<= v0.9.1)

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

Jetzt (>= v1.0.0)

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

Beachten Sie, dass Sie nicht mehr in passieren können functions.config().firebase bei der Initialisierung. Weitere Informationen zum Zugriff auf die Konfiguration in v1.0.0 finden Sie im folgenden Abschnitt.

functions.config().firebase entfernt

functions.config().firebase entfernt worden ist . Wenn Sie die Konfigurationswerte aus Ihrem Firebase Projekt zugreifen möchten, verwenden Sie process.env.FIREBASE_CONFIG statt:

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

SDK-Änderungen nach Triggertyp

Bei vielen unterstützten Funktionstriggern führte Version 1.0 Änderungen in der Benennung von Datenfeldern und Methoden ein. In diesem Abschnitt werden die Änderungen nach Triggertyp aufgelistet.

Echtzeit-Datenbank

Ereignisdaten jetzt ein DataSnapshot

In früheren Versionen event.data war ein DeltaSnapshot ; von 1,0 V weiter ist es eine DataSnapshot .

Für onWrite und onUpdate Ereignisse hat der Datenparameter before und after Feldern. Jeder von ihnen ist ein DataSnapshot mit denselben Methoden , in admin.database.DataSnapshot . Beispielsweise:

Vorher (<= 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
});

Jetzt (>= 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
});

Für onCreate ist der Datenparameter eine DataSnapshot , das die Daten darstellt , die gerade hinzugefügt wurde:

Vorher (<= v0.9.1)

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

Jetzt (>= v1.0.0)

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

Für onDelete ist der Datenparameter eine DataSnapshot , das die Daten darstellt , die gerade gelöscht wurde:

Vorher (<= v0.9.1)

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

Jetzt (>= v1.0.0)

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

Neue Eigenschaften für Benutzerauthentifizierungsinformationen

EventContext.auth V1.0.0 zwei neue Eigenschaften für Benutzer den Zugriff auf Informationen, einschließlich der Berechtigungen für den Benutzer , die eine Funktion ausgelöst.

  • EventContext.auth . Enthält Informationen wie uid und den authentifizierten Benutzer-Auth - Token.
  • EventContext.authType . Enthält Berechtigungsstufen, mit denen Sie beispielsweise erkennen können, ob der Benutzer ein Administrator ist.

Entwickler , die ohne Papiere mit event.auth Felder sollten alle damit verbundenen Code aktualisieren , um diese neuen Eigenschaften zu verwenden.

adminRef ersetzt durch ref

Die .adminRef Referenz wurde zugunsten der entfernten .ref Referenz , die jetzt mit Administratorrechten berechtigt ist. Die erstere Art der Verwendung .ref einen Verweis auf die Änderung als der Benutzer autorisiert -wie die den ausgelösten Wechsel wird nicht mehr unterstützt.

Vorher (<= 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.
});

Jetzt (>= 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
});

Sie können weiterhin vom Benutzer autorisierte Änderungen an der Echtzeitdatenbank mit dem Admin-SDK vornehmen:

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

Ähnlich wie die Echtzeit - Datenbank für v ändert 1.0, onWrite und onUpdate haben einen Datenparameter, der hat before und after Feldern. Event für onCreate und onDelete sowohl einen Datenparameter, die eine Wolke Firestor sind DocumentSnapshot .

Vorher (<= 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
});

Jetzt (>= 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
});

Events für onCreate und onDelete sowohl einen Datenparameter, die eine ist DocumentSnapshot .

Vorher (<= v0.9.1)

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

Jetzt (>= v1.0.0)

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

Breaking Change in v2.0.0 für Firestore-Zeitstempel

Ab v2.0.0 von Firebase SDK für Cloud - Funktionen, Zeitstempel - Werte in einem Firestor zur Momentaufnahme innerhalb einer Funktion empfingen Firestor Timestamp - Objekte. Dies gilt für snapshot.createTime , snapshot.updateTime , snapshot.readTime und alle Zeitstempel - Werte in snapshot.data()

Jetzt (>= 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);
});

Authentifizierung

In früheren Versionen event.data.metadata enthielt die veralteten Felder createdAt und lastSignedInAt . Version 1.0 beseitigt diese Felder vollständig aus und ersetzt sie durch creationTime und lastSignInTime Felder im userRecord.metadata Parameter.

Vorher (<= 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
}

Jetzt (>= 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

In v 1.0, dass der Ereignishandler jedes Mal ein neues Problem tritt feuert ist onNew . Der bisherige Handler genannt onNewDetected wurde entfernt.

Vorher (<= 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;
}

Jetzt (>= 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;
}

Cloud-Speicher

Der onChange Event - Handler wird entfernt. Stattdessen unterstützt v 1.0 diese Ereignisse:

  • onArchive nur gesendet , wenn ein Eimer aktiviert hat Objekt Versionierung . Dieses Ereignis zeigt an, dass die Live-Version eines Objekts zu einer archivierten Version geworden ist, entweder weil sie archiviert wurde oder weil sie durch den Upload eines gleichnamigen Objekts überschrieben wurde.
  • onDelete gesendet , wenn ein Objekt dauerhaft gelöscht wurde. Dazu gehören Objekte , die überschrieben werden oder als Teil der Schaufel des gelöschten Lifecycle - Konfiguration . Für Eimer mit Objektversionierung aktiviert ist , wird dies nicht gesendet , wenn ein Objekt archiviert wird (siehe onArchive ), auch wenn Archivierung über das auftritt storage.objects.delete Verfahren.
  • onFinalize gesendet , wenn ein neues Objekt (oder eine neue Generation eines bestehendes Objekt) wird erfolgreich in der Schaufel angelegt. Dazu gehört das Kopieren oder Umschreiben eines bestehenden Objekts. Ein fehlgeschlagener Upload löst dieses Ereignis nicht aus.
  • onMetadataUpdate gesendet , wenn die Metadaten eines vorhandenen Objekts ändert.

Vorher (<= 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;
  }

  // ...
}

Jetzt (>= 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

Da sich der zugrunde liegende Triggertyp geändert hat, müssen Sie Pub/Sub-Funktionen umbenennen und erneut bereitstellen. Es sind keine Änderungen am Funktionscode erforderlich.

So aktualisieren Sie Pub/Sub-Funktionen:

  1. Benennen Sie die Funktion um. Benennen Sie beispielsweise 'myPubSubFunction' in 'myNewPubSubFunction' um.
  2. Stellen Sie nur diese Funktion mithilfe einer teilweisen Bereitstellung bereit:

    firebase deploy --only functions:myNewPubSubFunction

  3. Löschen Sie nach der erfolgreichen Bereitstellung von 'myNewPubSubFunction' die veraltete Funktion vor Version 1.0.0, indem Sie alle Funktionen bereitstellen:

    firebase deploy --only functions

Während des kurzen Zeitraums zwischen diesen Bereitstellungsbefehlen erhalten Sie möglicherweise doppelte Trigger. Um diesen Fall zu handhaben und für den normalen Betrieb, stellen Sie sicher, Schreib Idempotent Funktionen .

Um mehr zu erfahren, finden Sie in der API - Referenz .

Änderungen an der Funktionsemulation

  • firebase serve dient nun beide HTTP - Funktionen und Hosting standardmäßig.
  • firebase experimental:functions:shell , die alle Funktionen emuliert, wurde umbenannt firebase functions:shell .

Syntaxänderungen für die Funktionsshell

Die Syntax zum Aufrufen von Funktionen über die Funktionsshell wurde aktualisiert, um die Syntax für Firebase-Funktionen v1.0.0+ widerzuspiegeln.

// 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’)