Cloud Firestore'u Cloud Functions ile Genişletin

Cloud Functions ile Cloud Firestore veritabanınızdaki değişikliklerin tetiklediği olayları yönetmek için Node.js kodunu dağıtabilirsiniz. Bu, kendi sunucularınızı çalıştırmanıza gerek kalmadan uygulamanıza kolayca sunucu tarafı işlevselliği eklemenizi sağlar.

Kullanım örnekleri örnekleri için bkz. Bulut İşlevleriyle Ne Yapabilirim? veya İşlev Örnekleri GitHub deposu.

Cloud Firestore işlevi tetikleyicileri

Firebase için Cloud Functions SDK'sı, belirli Cloud Firestore olaylarına bağlı işleyiciler oluşturmanıza olanak tanıyan bir functions.firestore nesnesini dışa aktarır.

Etkinlik tipi Tetiklemek
onCreate Bir belgeye ilk kez yazıldığında tetiklenir.
onUpdate Bir belge zaten mevcut olduğunda ve herhangi bir değeri değiştiğinde tetiklenir.
onDelete Veri içeren bir belge 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 kurmak için Başlayın: İlk İşlevlerinizi Yazın ve Dağıtın bölümünü okuyun.

Cloud Firestore tarafından tetiklenen işlevleri yazma

Bir işlev tetikleyicisi tanımlayın

Cloud Firestore tetikleyicisini tanımlamak için bir belge yolu ve olay türü belirtin:

Node.js

const functions = require('firebase-functions');

exports.myFunction = functions.firestore
  .document('my-collection/{docId}')
  .onWrite((change, context) => { /* ... */ });

Belge yolları belirli bir belgeye veya joker karakter desenine referans verebilir.

Tek bir belge belirtin

Belirli bir belgede herhangi bir değişiklik için bir olayı 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 belge grubu belirtin

Belirli bir koleksiyondaki herhangi bir belge gibi bir grup belgeye tetikleyici eklemek istiyorsanız belge kimliği yerine bir {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 herhangi bir belgedeki herhangi bir alan değiştirildiğinde, userId adı verilen bir joker karakterle eşleşir.

users bir belgenin alt koleksiyonları varsa ve bu alt koleksiyonların belgelerinden birindeki alan değiştirilirse userId joker karakteri tetiklenmez .

Joker karakter eşleşmeleri belge yolundan çıkarılır ve context.params dosyasında saklanır. Açık koleksiyon veya belge kimliklerinin yerine 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 belge oluşturulduğunda bir işlevi tetikleyin

Bir koleksiyonda yeni bir belge oluşturulduğunda herhangi bir zamanda tetiklenecek bir işlevi, onCreate() işleyicisini joker karakterle kullanarak tetikleyebilirsiniz. Bu örnek işlev, her yeni kullanıcı profili eklendiğinde createUser ç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 belge güncellendiğinde bir işlevi tetikleyin

Ayrıca onUpdate() işlevini joker karakterle kullanarak bir belge güncellendiğinde bir işlevin tetiklenmesini de tetikleyebilirsiniz. Bu örnek işlev, bir kullanıcı profilini değiştirirse updateUser ç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 belge silindiğinde bir işlevi tetikleyin

Bir belge silindiğinde onDelete() işlevini joker karakterle kullanarak da bir işlevi tetikleyebilirsiniz. Bu örnek işlev, bir kullanıcı kullanıcı profilini sildiğinde deleteUser çağırı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 belgedeki tüm değişiklikler için bir işlevi tetikleyin

Ateşlenen olayın türü umurumda değilse, joker karakterle onWrite() işlevini kullanarak Cloud Firestore belgesindeki tüm değişiklikleri dinleyebilirsiniz. Bu örnek işlev, bir kullanıcı oluşturulursa, güncellenirse veya silinirse, modifyUser ç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 olayla ilgili verilerin anlık görüntüsünü sağlar. Etkinliği tetikleyen belgeyi okumak veya belgeye yazmak için bu anlık görüntüyü kullanabilir veya veritabanınızın diğer bölümlerine erişmek için Firebase Admin SDK'yı kullanabilirsiniz.

Etkinlik Verileri

Veri Okuma

Bir işlev tetiklendiğinde, güncellenen bir belgeden veri almak veya verileri güncellemeden önce almak isteyebilirsiniz. Güncellemeden önceki belge anlık görüntüsünü içeren change.before.data() işlevini kullanarak önceki verileri alabilirsiniz. Benzer şekilde change.after.data() , güncelleme sonrasında belgenin 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, başka herhangi bir nesnede 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ünün ref özelliğinde DocumentReference olarak erişebilirsiniz.

Bu DocumentReference Cloud Firestore Node.js SDK'sından gelir ve update() , set() ve remove() gibi yöntemleri 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 olayın dışındaki veriler

Bulut İşlevleri güvenilir bir ortamda yürütülür; bu, projenizde hizmet hesabı olarak yetkilendirildikleri anlamına gelir. Firebase Admin SDK'yı 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'a yönelik Cloud Firestore tetikleyicilerine ilişkin aşağıdaki sınırlamalara dikkat edin:

  • Sipariş garanti edilmez. Hızlı değişiklikler, işlev çağrılarını beklenmedik bir sırada tetikleyebilir.
  • Olaylar en az bir kez iletilir, ancak tek bir olay birden fazla işlevin çağrılmasına neden olabilir. Tam olarak bir kez mekaniğine bağlı kalmaktan kaçının ve eşpotansiyel fonksiyonlar yazın.
  • Datastore modunda Cloud Firestore, Cloud Functions (2. nesil) gerektirir. Cloud Functions (1. nesil), Datastore modunu desteklemez.
  • Cloud Functions (1. nesil) yalnızca "(varsayılan)" veritabanıyla çalışır ve Cloud Firestore adlı veritabanlarını desteklemez. Adlandırılmış veritabanlarına yönelik etkinlikleri yapılandırmak için lütfen Bulut İşlevlerini (2. nesil) kullanın.
  • Bir tetikleyici tek bir veritabanıyla ilişkilidir. Birden fazla veritabanıyla eşleşen bir tetikleyici oluşturamazsınız.
  • Bir veritabanının silinmesi, o veritabanına ilişkin tetikleyicilerin otomatik olarak silinmesine neden olmaz. Tetikleyici, etkinliklerin yayınlanmasını durdurur ancak siz tetikleyiciyi silene kadar varlığını sürdürür.
  • Eşleşen bir etkinlik maksimum istek boyutunu aşarsa etkinlik Cloud Functions'a (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 Gezgini'nde "1. nesil için sınırı aşan boyut nedeniyle olay Bulut işlevine teslim edilemiyor..." mesajıyla birlikte error ciddiyetinde bulabilirsiniz. İşlev adını, functionName alanı altında bulabilirsiniz. receiveTimestamp alanı şu andan itibaren hâlâ bir saat içindeyse, söz konusu belgeyi zaman damgasından önceki ve sonraki anlık görüntüyle okuyarak gerçek olay içeriğini anlayabilirsiniz.
    • Böyle bir ritimden kaçınmak için şunları yapabilirsiniz:
      • Cloud Functions'a (2. nesil) geçiş ve yükseltme
      • Belgeyi küçültün
      • Söz konusu Bulut İşlevlerini silin
    • Hariç tutmaları kullanarak günlüğe kaydetmeyi kapatabilirsiniz ancak rahatsız edici olayların yine de teslim edilmeyeceğini unutmayın.