Cloud Firestore tetikleyicileri


Cloud Functions ile, istemci kodunu güncellemenize gerek kalmadan Cloud Firestore'daki etkinlikleri işleyebilirsiniz. Cloud Firestore değişikliklerini belge anlık görüntüsü arayüzü veya Admin SDK aracılığıyla yapabilirsiniz.

Tipik bir yaşam döngüsünde, Cloud Firestore işlevi şunları yapar:

  1. Belirli bir dokümanda değişiklik yapılmasını bekler.
  2. Bir etkinlik gerçekleştiğinde tetiklenir ve görevlerini yerine getirir.
  3. Belirtilen belgede depolanan verilerin anlık görüntüsünü içeren bir veri nesnesi alır. Yazma veya güncelleme etkinliklerinde, veri nesnesi tetikleme etkinliğinden ö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 bir ağ gecikmesine neden olabilir. Performansı optimize etmek için uygun olduğunda işlev konumunu belirtmeyi düşünebilirsiniz.

Cloud Firestore işlevi tetikleyicileri

Cloud Functions for Firebase SDK, belirli Cloud Firestore etkinliklerine bağlı işleyiciler oluşturmanıza olanak tanıyan bir functions.firestore nesnesi dışa aktarır.

Etkinlik Türü Tetikleyici
onCreate Bir dokümana ilk kez yazıldığında tetiklenir.
onUpdate Halihazırda mevcut olan bir dokümanda herhangi bir değer değiştirildiğinde tetiklenir.
onDelete Veri içeren bir doküman silindiğinde tetiklenir.
onWrite onCreate, onUpdate veya onDelete tetiklendiğinde tetiklenir.

Henüz 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şlevleri 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ümanda herhangi bir değişiklik yapıldığında 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 karakterler kullanarak bir grup belge belirtme

Belirli bir koleksiyondaki tüm belgeler gibi bir belge grubuna tetikleyici eklemek istiyorsanız belge 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 dokümanda yer alan herhangi bir alan değiştirildiğinde userId adlı bir joker karakterle eşleşir.

users içindeki bir dokümanda alt koleksiyonlar varsa ve bu alt koleksiyonlardaki dokümanlardan birinde alan değiştirilirse userId joker karakteri tetiklenmez.

Joker karakter eşleşmeleri, belge yolundan ayıklanır ve context.params içine depolanır. Açık koleksiyon veya belge kimliklerinin yerine geçecek istediğiniz kadar 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

Bir koleksiyonda yeni bir doküman oluşturulduğunda işlev tetiklemek için joker karakter içeren bir onCreate() işleyici kullanabilirsiniz. Bu örnek işlev, her yeni kullanıcı profili eklendiğinde createUser çağrısı yapar:

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şlev tetikleme

Ayrıca, joker içeren onUpdate() işlevini kullanarak bir doküman güncellendiğinde tetiklenecek bir işlev de oluşturabilirsiniz. Bu örnek işlev, 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

Bir belge silindiğinde joker karakter içeren onDelete() işlevini kullanarak da bir işlevi tetikleyebilirsiniz. Bu örnekte, kullanıcı kendi kullanıcı profilini sildiğinde deleteUser işlev çağrıları 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ümanda yapılan tüm değişiklikler için bir işlevi tetikleme

Tetiklenen etkinliğin türüyle ilgilenmiyorsanız onWrite() işlevini joker karakterle kullanarak Cloud Firestore belgesindeki tüm değişiklikleri dinleyebilirsiniz. Bu örnek işlev, bir kullanıcı oluşturulursa, güncellenirse veya silinirse modifyUser işlemini ç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 ...
    });

Veri Okuma ve Yazma

Bir işlev tetiklendiğinde, etkinlikle ilgili verilerin anlık görüntüsünü sağlar. Bu anlık görüntüyü, etkinliği tetikleyen dokümandan okumak veya bu dokümana yazmak için kullanabilir ya da Firebase Admin SDK'yı kullanarak veritabanınızın diğer bölümlerine erişebilirsiniz.

Etkinlik Verileri

Verileri Okuma

Bir işlev tetiklendiğinde, güncellenen bir dokümandaki verileri 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 verilere ulaşabilirsiniz. Benzer şekilde, change.after.data(), güncellemeden sonraki doküman anlık görüntüsünün 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');

Veri Yazma

Her işlev çağrısı, Cloud Firestore veritabanınızdaki belirli bir belgeyle ilişkilendirilir. Bu belgeye, işlevinize döndürülen anlık görüntü özelliğinin ref özelliğinde DocumentReference olarak erişebilirsiniz.

Bu DocumentReference, Cloud Firestore Node.js SDK'sından gelir ve update(), set() ve remove() gibi yöntemler içerir. Böylece, işlevi tetikleyen belgeyi kolayca değiştirebilirsiniz.

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 etkinlik 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 gerçekleştirebilirsiniz:

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) için Firestore yerel modunda mevcut bir "(default)" veritabanı gerekir. Cloud Firestore adlı veritabanları veya Datastore modu desteklenmez. Bu tür durumlarda etkinlikleri yapılandırmak için lütfen Cloud Functions (2. nesil) kullanın.
  • Sipariş verme garantisi yoktur. Hızlı değişiklikler, işlev çağrılarının beklenmedik bir sırada tetiklenmesine neden olabilir.
  • Etkinlikler en az bir kez teslim edilir ancak tek bir etkinlik birden fazla işlev çağrısına neden olabilir. Tam olarak bir kez mekanizmalarına bağlı kalmaktan kaçının ve idempotent işlevler yazın.
  • Cloud Firestore Datastore modunda 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ın silinmesi, o veritabanıyla ilgili tetikleyicileri otomatik olarak silmez. Tetikleyici, etkinlikleri yayınlamayı durdurur ancak tetikleyiciyi silene kadar varlığını sürdürür.
  • Eşleşen bir etkinlik maksimum istek boyutunu aşarsa etkinlik Cloud Functions'ye (1. nesil) teslim edilmeyebilir.
    • İstek boyutu nedeniyle teslim edilmeyen etkinlikler platform günlüklerine kaydedilir ve projenin günlük kullanımına dahil edilir.
    • Bu günlükleri, günlük gezgininde error önem derecesinde "Event cannot deliver to Cloud function due to size exceeding the limit for 1st gen..." (Boyut, 1. nesil için sınırı aştığından etkinlik Cloud işlevine teslim edilemiyor) mesajıyla bulabilirsiniz. İşlev adını functionName alanında bulabilirsiniz. receiveTimestamp alanı, şu andan itibaren bir saat içinde ise söz konusu dokümanı zaman damgasından önce ve sonraki anlık görüntülerle okuyarak gerçek etkinlik içeriğini çıkarabilirsiniz.
    • Bu tür bir ritmi önlemek için:
      • Cloud Functions'a (2. nesil) taşıma ve yükseltme
      • Belgeyi küçültme
      • Söz konusu Cloud Functions öğesini silin.
    • Hariç tutmaları kullanarak günlük kaydını tamamen devre dışı bırakabilirsiniz. Ancak, sorunlu etkinliklerin yine de teslim edilmeyeceğini unutmayın.