Cloud Firestore 觸發器

借助 Cloud Functions,您無需更新客戶端代碼即可處理 Cloud Firestore 中的事件。您可以通過雲計算公司的FireStore變化DocumentSnapshot接口或管理員SDK

在典型的生命週期中,Cloud Firestore 函數執行以下操作:

  1. 等待對特定文檔的更改。
  2. 觸發事件發生時,並執行其任務(見我可以用雲功能做些什麼?有關使用案例的例子)。
  3. 接收一個數據對象,該對象包含存儲在指定文檔中的數據的快照。對於onWriteonUpdate事件時,數據對象包含兩個快照之前和在觸發事件之後代表數據狀態。

Firestore 實例的位置與函數的位置之間的距離會造成顯著的網絡延遲。為了優化性能,考慮指定的功能定位適用的地方。

Cloud Firestore 函數觸發器

對於火力地堡SDK雲功能導出一個functions.firestore對象允許您創建處理程序綁定到特定的雲公司的FireStore事件。

事件類型扳機
onCreate第一次寫入文檔時觸發。
onUpdate當文檔已經存在並且有任何值更改時觸發。
onDelete刪除包含數據的文檔時觸發。
onWrite當觸發onCreateonUpdateonDelete被觸發。

如果你沒有為火力地堡雲功能啟用了一個項目還沒有做,然後閱讀入門:編寫和部署你的第一個功能配置和設置您的雲功能的火力地堡項目。

編寫 Cloud Firestore 觸發的函數

定義函數觸發器

要定義 Cloud Firestore 觸發器,請指定文檔路徑和事件類型:

節點.js

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

exports.myFunction = functions.firestore
  .document('my-collection/{docId}')
  .onWrite((change, context) => { /* ... */ });

文件路徑可以引用特定文檔或一個通配符模式

指定單個文檔

如果要觸發任何改變的情況下,以一個特定的文件,那麼你可以使用下面的函數。

節點.js

// Listen for any change on document `marie` in collection `users`
exports.myFunctionName = functions.firestore
    .document('users/marie').onWrite((change, context) => {
      // ... Your code here
    });

使用通配符指定一組文檔

如果要觸發連接到一組文件,如在某一集的任何文件,然後用{wildcard}代替文檔ID:

節點.js

// Listen for changes in all documents in the 'users' collection
exports.useWildcard = functions.firestore
    .document('users/{userId}')
    .onWrite((change, context) => {
      // If we set `/users/marie` to {name: "Marie"} then
      // context.params.userId == "marie"
      // ... and ...
      // change.after.data() == {name: "Marie"}
    });

在這個例子中,當在任何文件的任何字段users改變時,它被稱為通配符匹配userId

如果在文檔users有子集,並在這些子集“文件中的一個字段被改變, userId通配符不會被觸發。

通配符匹配被從文檔中提取路徑並存儲到context.params 。您可以定義任意數量的通配符來替換顯式集合或文檔 ID,例如:

節點.js

// Listen for changes in all documents in the 'users' collection and all subcollections
exports.useMultipleWildcards = functions.firestore
    .document('users/{userId}/{messageCollectionId}/{messageId}')
    .onWrite((change, context) => {
      // If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then
      // context.params.userId == "marie";
      // context.params.messageCollectionId == "incoming_messages";
      // context.params.messageId == "134";
      // ... and ...
      // change.after.data() == {body: "Hello"}
    });

事件觸發器

創建新文檔時觸發功能

您可以觸發功能,通過使用火一個新文檔集合中創建的任何時間onCreate()處理程序與一個通配符。這個例子函數調用createUser每次添加新的用戶配置文件時間:

節點.js

exports.createUser = functions.firestore
    .document('users/{userId}')
    .onCreate((snap, context) => {
      // Get an object representing the document
      // e.g. {'name': 'Marie', 'age': 66}
      const newValue = snap.data();

      // access a particular field as you would any JS property
      const name = newValue.name;

      // perform desired operations ...
    });

文檔更新時觸發函數

您還可以觸發功能火災當文檔使用更新onUpdate()與函數通配符。這個例子函數調用updateUser如果用戶更改他們的個人資料:

節點.js

exports.updateUser = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
      // Get an object representing the document
      // e.g. {'name': 'Marie', 'age': 66}
      const newValue = change.after.data();

      // ...or the previous value before this update
      const previousValue = change.before.data();

      // access a particular field as you would any JS property
      const name = newValue.name;

      // perform desired operations ...
    });

刪除文檔時觸發函數

當一個文檔使用刪除您也可以觸發功能onDelete()與函數通配符。這個例子函數調用deleteUser當用戶刪除他們的用戶配置文件:

節點.js

exports.deleteUser = functions.firestore
    .document('users/{userID}')
    .onDelete((snap, context) => {
      // Get an object representing the document prior to deletion
      // e.g. {'name': 'Marie', 'age': 66}
      const deletedValue = snap.data();

      // perform desired operations ...
    });

為文檔的所有更改觸發一個函數

如果你不關心事件被解僱的類型,你可以聽使用雲公司的FireStore文檔中的所有變化onWrite()函數用通配符。這個例子函數調用modifyUser如果創建了一個用戶,更新或刪除:

節點.js

exports.modifyUser = functions.firestore
    .document('users/{userID}')
    .onWrite((change, context) => {
      // Get an object with the current document value.
      // If the document does not exist, it has been deleted.
      const document = change.after.exists ? change.after.data() : null;

      // Get an object with the previous document value (for update or delete)
      const oldDocument = change.before.data();

      // perform desired operations ...
    });

讀寫數據

當一個函數被觸發時,它會提供與事件相關的數據的快照。您可以使用此快照讀取或寫入觸發事件的文檔,或使用 Firebase Admin SDK 訪問數據庫的其他部分。

事件數據

讀取數據

當函數被觸發時,您可能希望從更新的文檔中獲取數據,或者獲取更新前的數據。您可以通過使用獲得前數據change.before.data()其中包含更新前的文件快照。同樣, change.after.data()包含更新後的文件快照狀態。

節點.js

exports.updateUser2 = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
      // Get an object representing the current document
      const newValue = change.after.data();

      // ...or the previous value before this update
      const previousValue = change.before.data();
    });

您可以像訪問任何其他對像一樣訪問屬性。另外,您也可以使用get功能來訪問特定的字段:

節點.js

// Fetch data using standard accessors
const age = snap.data().age;
const name = snap.data()['name'];

// Fetch data using built in accessor
const experience = snap.get('experience');

寫入數據

每個函數調用都與 Cloud Firestore 數據庫中的特定文檔相關聯。您可以訪問該文檔作為一個DocumentReferenceref返回到您的功能快照的屬性。

DocumentReference來自雲公司的FireStore的Node.js SDK包括了如方法update() set()remove()所以你可以很容易地修改觸發功能的文檔。

節點.js

// Listen for updates to any `user` document.
exports.countNameChanges = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
      // Retrieve the current and previous value
      const data = change.after.data();
      const previousData = change.before.data();

      // We'll only update if the name has changed.
      // This is crucial to prevent infinite loops.
      if (data.name == previousData.name) {
        return null;
      }

      // Retrieve the current count of name changes
      let count = data.name_change_count;
      if (!count) {
        count = 0;
      }

      // Then return a promise of a set operation to update the count
      return change.after.ref.set({
        name_change_count: count + 1
      }, {merge: true});
    });

觸發事件之外的數據

Cloud Functions 在受信任的環境中執行,這意味著它們被授權為您項目的服務帳戶。您可以執行讀取和使用寫入火力地堡管理SDK

節點.js

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

const db = admin.firestore();

exports.writeToFirestore = functions.firestore
  .document('some/doc')
  .onWrite((change, context) => {
    db.doc('some/otherdoc').set({ ... });
  });

限制

請注意 Cloud Functions 的 Cloud Firestore 觸發器的以下限制:

  • 不能保證訂購。快速更改可能會以意外的順序觸發函數調用。
  • 事件至少傳遞一次,但單個事件可能會導致多個函數調用。避免依賴於恰好一次力學,寫冪等功能
  • 雲公司的FireStore觸發雲功能僅適用於使用雲公司的FireStore本機模式。它不適用於 Datastore 模式下的 Cloud Firestore。