Cloud Functions ile istemci kodunu güncellemenize gerek kalmadan Cloud Firestore'daki etkinlikleri yönetebilirsiniz. Cloud Firestore değişikliklerini, belge anlık görüntüsü arayüzü veya Admin SDK üzerinden yapabilirsiniz.
Tipik bir yaşam döngüsünde Cloud Firestore işlevi şunları yapar:
- Belirli bir dokümanda değişiklik yapılmasını bekler.
- Bir etkinlik gerçekleştiğinde tetiklenir ve görevlerini yerine getirir.
- Belirtilen dokümanda depolanan verilerin anlık görüntüsünü içeren bir veri nesnesi alır. Yazma veya güncelleme etkinlikleri için veri nesnesi, tetikleyici etkinlikten önceki ve sonraki veri durumunu temsil eden iki anlık görüntü içerir.
Firestore örneğinin konumu ile işlevin konumu arasındaki mesafe, önemli ağ gecikmelerine neden olabilir. Performansı optimize etmek için uygun durumlarda işlev konumunu belirtmeyi düşünün.
Cloud Firestore işlev tetikleyicileri
Cloud Functions for Firebase SDK'sı, belirli Cloud Firestore etkinliklerine bağlı işleyiciler oluşturmanıza olanak tanıyan bir functions.firestore nesnesini dışa aktarır.
| Etkinlik Türü | Tetikleyici |
|---|---|
onCreate |
Bir dokümana ilk kez yazıldığında tetiklenir. |
onUpdate |
Mevcut bir dokümandaki herhangi bir değer değiştiğinde tetiklenir. |
onDelete |
Veri içeren bir doküman silindiğinde tetiklenir. |
onWrite |
onCreate, onUpdate veya onDelete tetiklendiğinde tetiklenir. |
Cloud Functions for Firebase için etkinleştirilmiş bir projeniz yoksa Cloud Functions for Firebase projenizi yapılandırmak ve ayarlamak için Başlangıç: İlk İşlevlerinizi Yazma ve Dağıtma başlıklı makaleyi okuyun.
Cloud Firestore tarafından tetiklenen işlevler yazma
İşlev tetikleyicisi tanımlama
Cloud Firestore tetikleyicisi tanımlamak için bir doküman yolu ve etkinlik türü belirtin:
Node.js
const functions = require('firebase-functions');
exports.myFunction = functions.firestore
.document('my-collection/{docId}')
.onWrite((change, context) => { /* ... */ });
Doküman yolları, belirli bir dokümana veya joker karakter kalıbına başvurabilir.
Tek bir doküman belirtme
Belirli bir dokümandaki herhangi bir değişiklik için bir etkinlik tetiklemek istiyorsanız aşağıdaki işlevi kullanabilirsiniz.
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 });
Joker karakterleri kullanarak bir doküman grubu belirtme
Belirli bir koleksiyondaki tüm dokümanlar gibi bir doküman grubuna tetikleyici eklemek istiyorsanız doküman kimliği yerine {wildcard} kullanın:
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"} });
Bu örnekte, users içindeki herhangi bir belgede herhangi bir alan değiştirildiğinde userId adlı joker karakterle eşleşir.
users içindeki bir belgede alt koleksiyonlar varsa ve bu alt koleksiyonların belgelerindeki bir alan değiştirilirse userId joker karakteri tetiklenmez.
Joker karakter eşleşmeleri, doküman yolundan ayıklanır ve context.params içinde depolanır.
Açık koleksiyon veya belge kimliklerinin yerine kullanmak üzere istediğiniz sayıda joker karakter tanımlayabilirsiniz. Örneğin:
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"} });
Etkinlik Tetikleyicileri
Yeni bir doküman oluşturulduğunda işlevi tetikleme
Joker karakter içeren bir onCreate() işleyici kullanarak bir koleksiyonda yeni bir doküman oluşturulduğunda tetiklenecek bir işlev oluşturabilirsiniz.
Bu örnek işlev, her yeni kullanıcı profili eklendiğinde createUser işlevini çağırır:
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 ... });
Bir doküman güncellendiğinde işlevi tetikleme
Ayrıca, joker karakter içeren onUpdate() işlevini kullanarak bir doküman güncellendiğinde tetiklenecek bir işlev de oluşturabilirsiniz. Bu örnek işlev, bir kullanıcı profilini değiştirirse updateUser işlevini çağırır:
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 ... });
Bir doküman silindiğinde işlev tetikleme
Joker karakter içeren onDelete() işlevini kullanarak bir doküman silindiğinde de işlev tetikleyebilirsiniz. Bu örnekte, kullanıcı profilini sildiğinde deleteUser işlev çağrısı yapılır:
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 ... });
Bir dokümandaki tüm değişiklikler için işlev tetikleme
Tetiklenen etkinliğin türü sizin için önemli değilse joker karakter içeren onWrite() işlevini kullanarak Cloud Firestore belgesindeki tüm değişiklikleri dinleyebilirsiniz. Bu örnek işlev, bir kullanıcı oluşturulduğunda, güncellendiğinde veya silindiğinde modifyUser işlevini çağırır:
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 ... });
Okuma ve Yazma Verileri
Tetiklenen işlev, etkinlikle ilgili verilerin anlık görüntüsünü sağlar. Bu anlık görüntüyü, etkinliği tetikleyen dokümanı okumak veya dokümana yazmak için kullanabilirsiniz. Veritabanınızın diğer bölümlerine erişmek için Firebase Admin SDK'yı da kullanabilirsiniz.
Etkinlik Verileri
Verileri Okuma
Bir işlev tetiklendiğinde güncellenen bir dokümandan veri almak veya güncellemeden önceki verileri almak isteyebilirsiniz. Güncellemeden önceki doküman anlık görüntüsünü içeren change.before.data() kullanarak önceki verileri alabilirsiniz.
Benzer şekilde, change.after.data(), güncellemeden sonraki doküman anlık görüntü durumunu içerir.
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(); });
Özelliklere diğer nesnelerde olduğu gibi erişebilirsiniz. Alternatif olarak, belirli alanlara erişmek için get işlevini kullanabilirsiniz:
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');
Yazma Verileri
Her işlev çağrısı, Cloud Firestore veritabanınızdaki belirli bir dokümanla ilişkilendirilir. Bu dokümana, işlevinize döndürülen anlık görüntünün ref özelliğinde DocumentReference olarak erişebilirsiniz.
Bu DocumentReference, Cloud Firestore Node.js SDK'sından gelir
ve işlevi tetikleyen dokümanı kolayca değiştirebilmeniz için update(), set() ve remove() gibi yöntemler içerir.
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}); });
Tetikleyici etkinliğin dışındaki veriler
Cloud Functions, güvenilir bir ortamda yürütülür. Bu, projenizde hizmet hesabı olarak yetkilendirildikleri anlamına gelir. Firebase Admin SDK'sını kullanarak okuma ve yazma işlemleri yapabilirsiniz:
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({ ... });
});
Sınırlamalar
Cloud Functions için Cloud Firestore tetikleyicileriyle ilgili aşağıdaki sınırlamalara dikkat edin:
- Cloud Functions (1. nesil), Firestore yerel modunda mevcut bir "(default)" veritabanı gerektirir. Cloud Firestore adlandırılmış veritabanlarını veya Datastore modunu desteklemez. Bu gibi durumlarda etkinlikleri yapılandırmak için lütfen Cloud Functions (2. nesil) kullanın.
- Cloud Functions ve Cloud Firestore tetikleyicisiyle projeler arası kurulum bir sınırlamadır. Cloud Firestore tetikleyicisini ayarlamak için Cloud Functions aynı projede olmalıdır.
- Sıralama garanti edilmez. Hızlı değişiklikler, işlev çağrılarının beklenmedik bir sırada tetiklenmesine neden olabilir.
- Etkinlikler en az bir kez yayınlanır ancak tek bir etkinlik birden fazla işlev çağrısına neden olabilir. Tam olarak bir kez mekaniğine bağlı kalmaktan kaçının ve idempotent işlevler yazın.
- Datastore modunda Cloud Firestore, Cloud Functions (2. nesil) gerektirir. Cloud Functions (1. nesil) Datastore modunu desteklemez.
- Tetikleyici tek bir veritabanıyla ilişkilendirilir. Birden fazla veritabanıyla eşleşen bir tetikleyici oluşturamazsınız.
- Bir veritabanını sildiğinizde bu veritabanının tetikleyicileri otomatik olarak silinmez. Tetikleyici, etkinlikleri yayınlamayı durdurur ancak siz tetikleyiciyi silene kadar var olmaya devam eder.
- Eşleşen bir etkinlik maksimum istek boyutunu aşarsa etkinlik Cloud Functions (1. nesil) ürününe teslim edilmeyebilir.
- İstek boyutu nedeniyle yayınlanmayan etkinlikler platform günlüklerine kaydedilir ve projenin günlük kullanımına dahil edilir.
- Bu günlükleri, Günlük Gezgini'nde
errorönem derecesine sahip "Event cannot deliver to Cloud function due to size exceeding the limit for 1. nesil..." mesajıyla bulabilirsiniz. İşlev adınıfunctionNamealanında bulabilirsiniz.receiveTimestampalanı hâlâ şu andan itibaren bir saat içindeyse zaman damgasından önce ve sonra bir anlık görüntüyle söz konusu dokümanı okuyarak gerçek etkinlik içeriğini tahmin edebilirsiniz. - Bu tür bir sıklığı önlemek için şunları yapabilirsiniz:
- Cloud Functions (2. nesil) cihazına geçiş yapın ve yükseltin
- Dokümanı küçültme
- Söz konusu Cloud Functions öğesini silme
- İstisnalar'ı kullanarak günlük kaydını devre dışı bırakabilirsiniz ancak sorunlu etkinliklerin yine de yayınlanmayacağını unutmayın.