Cloud Functions を使用して Node.js コードをデプロイすることで、Cloud Firestore データベースの変更によってトリガーされるイベントを処理することができます。これにより、独自のサーバーを運用することなく、サーバー側の機能を簡単にアプリに追加できます。
使用例については、Cloud Functions で可能な処理または 関数サンプル GitHub レポジトリをご覧ください。
Cloud Firestore の関数をトリガーする
Cloud Functions for Firebase SDK は、特定のイベントのハンドラを作成できる functions.firestore
オブジェクトをエクスポートします。
Cloud Firestore は、create
、update
、delete
、write
イベントをサポートしています。
イベントタイプ | トリガー |
---|---|
onCreate |
ドキュメントが最初に書き込まれたときにトリガーされます。 |
onUpdate |
すでに存在するドキュメントの値が変更されたときにトリガーされます。 |
onDelete |
データを含むドキュメントが削除されたときにトリガーされます。 |
onWrite |
onCreate 、onUpdate または onDelete がトリガーされたときにトリガーされます。 |
プロジェクトを Cloud Functions for Firebase でまだ有効にしていない場合には、はじめに: 最初の関数の記述とデプロイを参照して、Cloud Functions for Firebase プロジェクトを設定します。
特定のドキュメントが変更されたときに関数をトリガーする
特定のドキュメントが変更されたときにイベントをトリガーするには、次の関数を使用します。
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
});
新しいドキュメントが作成されたときに関数をトリガーする
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 ...
});
ドキュメントが変更されたときに関数をトリガーする
発生するイベントの種類に関係なく、Cloud Firestore ドキュメントのすべての変更をリッスンするには、onWrite()
関数でワイルドカードを使用します。次の例の関数は、ユーザーが作成、更新、または削除されたときに 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 ...
});
イベントデータを処理する
データの読み取り
関数がトリガーされた後、更新済みのドキュメントのデータを取得する場合や、更新前のデータを取得する場合があります。更新前のデータは change.before.data()
を使用して取得できます。これには更新前のドキュメントのスナップショットが含まれます。同様に、change.after.data()
には更新後のドキュメントのスナップショットの状態が含まれます。
Node.js
exports.updateUser = 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;
// 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});
});
ワイルドカードとパラメータの使用
イベント トリガーを関連付けるドキュメントがわからない場合には、ドキュメント ID の代わりに {wildcard}
を使用できます。
Node.js
// Listen for changes in all documents and all sub-collections
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
ワイルドカードはトリガーされません。
ワイルドカードに一致した部分がドキュメント パスから抽出され、event.params
に保存されます。明示的なコレクションまたはドキュメント ID に置き換えるワイルドカードは、必要な数だけ定義できます。
Node.js
// Listen for changes in all documents 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"}
});
制約と保証
アプリケーションを開発する場合には、Cloud Firestore と Cloud Functions for Firebase が現在ともにベータ版であること、つまり予期しない動作が起きる可能性があるという点に注意してください。
次のような制約があります。
- Cloud Firestore のデータが変更されてから関数がトリガーされるまで 5 秒以上かかる場合があります。
- 現在、関数呼び出しの配信は保証されていません。Cloud Firestore と Cloud Functions の統合が向上した段階で、「at-least-once」配信を保証する予定です。ただし、ベータ版ではこれが保証されるとは限りません。1 つのイベントで複数の呼び出しが発生する可能性があるため、関数で高い精度が求められる場合には、関数の書き込みをべき等にする必要があります。
- 順序は保証されません。急激な変更を行うと、予期しない順序で関数が呼び出される可能性があります。