借助 Cloud Functions,您可以部署 Node.js 程式碼來處理由 Cloud Firestore 資料庫中的變更觸發的事件。這使您可以輕鬆地將伺服器端功能添加到您的應用程式中,而無需運行自己的伺服器。
有關用例範例,請參閱我可以使用 Cloud Functions 做什麼?或函數範例GitHub 儲存庫。
Cloud Firestore 函數觸發器
Cloud Functions for Firebase SDK 匯出一個functions.firestore
對象,讓您可以建立與特定 Cloud Firestore 事件關聯的處理程序。
事件類型 | 扳機 |
---|---|
onCreate | 第一次寫入文件時觸發。 |
onUpdate | 當文件已存在並且任何值發生變更時觸發。 |
onDelete | 當刪除包含資料的文件時觸發。 |
onWrite | 當觸發onCreate 、 onUpdate 或onDelete 時觸發。 |
如果您尚未為 Cloud Functions for Firebase 啟用項目,請閱讀入門:編寫和部署您的第一個 Functions以設定和設定您的 Cloud Functions for Firebase 項目。
編寫 Cloud Firestore 觸發的函數
定義函數觸發器
若要定義 Cloud Firestore 觸發器,請指定文件路徑和事件類型:
Node.js
const functions = require('firebase-functions');
exports.myFunction = functions.firestore
.document('my-collection/{docId}')
.onWrite((change, context) => { /* ... */ });
指定單一文檔
如果您想要針對特定文件的任何變更觸發事件,則可以使用下列函數。
Node.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:
Node.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,例如:
Node.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
:
Node.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
:
Node.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
:
Node.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 ... });
對文檔的所有更改觸發函數
如果您不關心觸發的事件類型,則可以使用帶有通配符的onWrite()
函數來偵聽 Cloud Firestore 文件中的所有變更。如果建立、更新或刪除用戶,此範例函數將呼叫modifyUser
:
Node.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()
包含更新後的文檔快照狀態。
Node.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
函數來存取特定欄位:
Node.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 資料庫中的特定文件相關聯。您可以在傳回函數的快照的ref
屬性中以DocumentReference
形式存取該文件。
此DocumentReference
來自Cloud Firestore Node.js SDK ,包含update()
、 set()
和remove()
等方法,因此您可以輕鬆修改觸發函數的文件。
Node.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 在受信任的環境中執行,這表示它們被授權為專案的服務帳戶。您可以使用Firebase Admin SDK執行讀取和寫入:
Node.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 觸發器的以下限制:
- 不保證訂購。快速變化可能會以意外的順序觸發函數呼叫。
- 事件至少傳遞一次,但單一事件可能會導致多個函數呼叫。避免依賴一次性機制,並寫出冪等函數。
- 資料儲存模式下的 Cloud Firestore需要 Cloud Functions(第二代)。 Cloud Functions(第一代)不支援資料儲存模式。
- Cloud Functions(第一代)僅適用於「(預設)」資料庫,不支援 Cloud Firestore 命名資料庫。請使用 Cloud Functions(第二代)為指定資料庫配置事件。
- 觸發器與單一資料庫關聯。您無法建立與多個資料庫相符的觸發器。
- 刪除資料庫不會自動刪除該資料庫的任何觸發器。觸發器停止傳送事件,但會繼續存在,直到您刪除觸發器。
- 如果符合的事件超出最大請求大小,則該事件可能不會傳遞到 Cloud Functions(第一代)。