Cloud Functions를 사용하면 클라이언트 코드를 업데이트할 필요 없이 Cloud Firestore에서 이벤트를 처리할 수 있습니다. DocumentSnapshot
인터페이스 또는 Admin SDK 를 통해 Cloud Firestore를 변경할 수 있습니다.
일반적인 수명 주기에서 Cloud Firestore 기능은 다음을 수행합니다.
- 특정 문서가 변경될 때까지 기다립니다.
- 이벤트가 발생할 때 트리거하고 작업을 수행합니다(사용 사례의 예는 Cloud Functions로 무엇을 할 수 있나요? 참조).
- 지정된 문서에 저장된 데이터의 스냅샷이 포함된 데이터 개체를 받습니다.
onWrite
또는onUpdate
이벤트의 경우 데이터 개체에는 트리거 이벤트 전후의 데이터 상태를 나타내는 두 개의 스냅샷이 포함됩니다.
Firestore 인스턴스 위치와 함수 위치 사이의 거리로 인해 상당한 네트워크 지연 시간이 발생할 수 있습니다. 성능을 최적화하려면 해당하는 경우 함수 위치 를 지정하는 것이 좋습니다.
Cloud Firestore 함수 트리거
Firebase용 Cloud Functions SDK는 특정 Cloud Firestore 이벤트에 연결된 핸들러를 생성할 수 있는 functions.firestore
객체를 내보냅니다.
이벤트 유형 | 방아쇠 |
---|---|
onCreate | 문서를 처음 쓸 때 트리거됩니다. |
onUpdate | 문서가 이미 존재하고 값이 변경된 경우 트리거됩니다. |
onDelete | 데이터가 있는 문서가 삭제될 때 트리거됩니다. |
onWrite | onCreate , onUpdate 또는 onDelete 가 트리거될 때 트리거됩니다. |
Firebase용 Cloud Functions에 대해 아직 활성화된 프로젝트가 없는 경우 시작하기: 첫 번째 함수 작성 및 배포 를 읽고 Firebase용 Cloud Functions 프로젝트를 구성하고 설정하세요.
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 });
와일드카드를 사용하여 문서 그룹 지정
특정 컬렉션의 문서와 같은 문서 그룹에 트리거를 연결하려면 문서 ID 대신 {wildcard}
를 사용하세요.
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 Functions용 Cloud Firestore 트리거 는 기본 모드의 Cloud Firestore 에서만 사용할 수 있습니다. Datastore 모드의 Cloud Firestore에서는 사용할 수 없습니다.