Gerçek Zamanlı Veritabanı tetikleyicileri


Cloud Functions ile Firebase Gerçek Zamanlı Veritabanındaki olayları istemci kodunu güncellemeye gerek kalmadan işleyebilirsiniz. Cloud Functions, Gerçek Zamanlı Veritabanı işlemlerini tam yönetici ayrıcalıklarıyla çalıştırmanıza olanak tanır ve Gerçek Zamanlı Veritabanında yapılan her değişikliğin ayrı ayrı işlenmesini sağlar. Firebase Realtime Database değişikliklerini DataSnapshot veya Admin SDK aracılığıyla yapabilirsiniz.

Tipik bir yaşam döngüsünde bir Firebase Gerçek Zamanlı Veritabanı işlevi aşağıdakileri yapar:

  1. Belirli bir Gerçek Zamanlı Veritabanı konumundaki değişiklikleri bekler.
  2. Bir olay meydana geldiğinde tetiklenir ve görevlerini yerine getirir (kullanım örnekleri için bkz . Bulut İşlevleri ile ne yapabilirim? ).
  3. Belirtilen belgede depolanan verilerin anlık görüntüsünü içeren bir veri nesnesi alır.

Gerçek Zamanlı Veritabanı işlevini tetikleyin

functions.database ile Gerçek Zamanlı Veritabanı olayları için yeni işlevler oluşturun. İşlevin ne zaman tetikleneceğini kontrol etmek için olay işleyicilerinden birini belirtin ve olayları dinleyeceği Gerçek Zamanlı Veritabanı yolunu belirtin.

Olay işleyiciyi ayarla

İşlevler, Gerçek Zamanlı Veritabanı olaylarını iki düzeyde belirlilik düzeyinde işlemenize olanak tanır; yalnızca oluşturma, güncelleme veya silme olaylarını özel olarak dinleyebilir veya bir yoldaki herhangi bir değişikliği dinleyebilirsiniz. Cloud Functions, Realtime Database için şu olay işleyicileri destekler:

  • Gerçek Zamanlı Veritabanında veriler oluşturulduğunda, güncellendiğinde veya silindiğinde tetiklenen onWrite() .
  • Gerçek Zamanlı Veritabanında yeni veriler oluşturulduğunda tetiklenen onCreate() .
  • Gerçek Zamanlı Veritabanında veriler güncellendiğinde tetiklenen onUpdate() .
  • onDelete() , veriler Gerçek Zamanlı Veritabanından silindiğinde tetiklenir.

Örneği ve yolu belirtin

İşlevinizin ne zaman ve nerede tetiklenmesi gerektiğini kontrol etmek için, bir yol belirtmek üzere ref(path) öğesini çağırın ve isteğe bağlı olarak instance('INSTANCE_NAME') ile bir Realtime Database örneği belirtin. Bir örnek belirtmezseniz işlev, Firebase projesi için varsayılan Gerçek Zamanlı Veritabanı örneğine dağıtılır Örneğin:

  • Varsayılan Gerçek Zamanlı Veritabanı örneği: functions.database.ref('/foo/bar')
  • "my-app-db-2" adlı örnek: functions.database.instance('my-app-db-2').ref('/foo/bar')

Bu yöntemler, işlevinizi, Gerçek Zamanlı Veritabanı örneğinde belirli bir yoldaki yazmaları işlemeye yönlendirir. Yol belirtimleri, altında herhangi bir yerde gerçekleşen yazmalar da dahil olmak üzere bir yola temas eden tüm yazma işlemleriyle eşleşir. İşlevinizin yolunu /foo/bar olarak ayarlarsanız, bu konumların her ikisindeki olaylarla eşleşir:

 /foo/bar
 /foo/bar/baz/really/deep/path

Her iki durumda da Firebase, olayın /foo/bar adresinde gerçekleştiğini ve etkinlik verilerinin /foo/bar adresindeki eski ve yeni verileri içerdiğini yorumlar. Olay verileri büyük olabilirse, veritabanınızın köküne yakın tek bir işlev yerine daha derin yollarda birden çok işlev kullanmayı düşünün. En iyi performans için, verileri yalnızca mümkün olan en derin düzeyde isteyin.

Bir yol bileşenini kıvrık parantez içine alarak joker karakter olarak belirtebilirsiniz; ref('foo/{bar}') /foo öğesinin herhangi bir alt öğesiyle eşleşir. Bu joker yol bileşenlerinin değerleri, işlevinizin EventContext.params nesnesinde bulunur. Bu örnekte, değer şu şekilde mevcuttur: context.params.bar .

Joker karakterler içeren yollar, tek bir yazmadan birden çok olayla eşleşebilir. bir ekleme

{
  "foo": {
    "hello": "world",
    "firebase": "functions"
  }
}

"/foo/{bar}" yolunu iki kez eşleştirir: bir kez "hello": "world" ile ve tekrar "firebase": "functions" ile.

Olay verilerini işleme

Bir Gerçek Zamanlı Veritabanı olayı işlenirken, döndürülen veri nesnesi bir DataSnapshot . onWrite veya onUpdate olayları için ilk parametre, tetikleyici olaydan önceki ve sonraki veri durumunu temsil eden iki anlık görüntü içeren bir Change nesnesidir. onCreate ve onDelete olayları için döndürülen veri nesnesi, oluşturulan veya silinen verilerin anlık görüntüsüdür.

Bu örnekte işlev, belirtilen yol için anlık görüntüyü alır, o konumdaki dizeyi büyük harfe dönüştürür ve değiştirilen dizeyi veritabanına yazar:

// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();
      functions.logger.log('Uppercasing', context.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return snapshot.ref.parent.child('uppercase').set(uppercase);
    });

Kullanıcı kimlik doğrulama bilgilerine erişme

EventContext.auth ve EventContext.authType içinden, bir işlevi tetikleyen kullanıcının izinleri de dahil olmak üzere kullanıcı bilgilerine erişebilirsiniz. Bu, işlevinizin kullanıcının izin düzeyine göre farklı işlemleri tamamlamasına izin vererek güvenlik kurallarını uygulamak için yararlı olabilir:

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

exports.simpleDbFunction = functions.database.ref('/path')
    .onCreate((snap, context) => {
      if (context.authType === 'ADMIN') {
        // do something
      } else if (context.authType === 'USER') {
        console.log(snap.val(), 'written by', context.auth.uid);
      }
    });

Ayrıca, bir kullanıcının "kimliğine bürünmek" ve kullanıcı adına yazma işlemleri gerçekleştirmek için kullanıcı kimlik doğrulama bilgilerinden yararlanabilirsiniz. Eşzamanlılık sorunlarını önlemek için uygulama örneğini aşağıda gösterildiği gibi sildiğinizden emin olun:

exports.impersonateMakeUpperCase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snap, context) => {
      const appOptions = JSON.parse(process.env.FIREBASE_CONFIG);
      appOptions.databaseAuthVariableOverride = context.auth;
      const app = admin.initializeApp(appOptions, 'app');
      const uppercase = snap.val().toUpperCase();
      const ref = snap.ref.parent.child('uppercase');

      const deleteApp = () => app.delete().catch(() => null);

      return app.database().ref(ref).set(uppercase).then(res => {
        // Deleting the app is necessary for preventing concurrency leaks
        return deleteApp().then(() => res);
      }).catch(err => {
        return deleteApp().then(() => Promise.reject(err));
      });
    });

Önceki değeri okuma

Change nesnesi, olaydan önce Realtime Database'e neyin kaydedildiğini incelemenizi sağlayan bir before özelliğine sahiptir. before özelliği, tüm yöntemlerin (örneğin, val() ve exists() ) önceki değere başvurduğu bir DataSnapshot döndürür. Orijinal DataSnapshot kullanarak veya after özelliğini okuyarak yeni değeri tekrar okuyabilirsiniz. Herhangi bir Change bu özellik, olay gerçekleştikten sonra verilerin durumunu temsil eden başka bir DataSnapshot .

Örneğin, fonksiyonun ilk oluşturulduğunda metni yalnızca büyük harfle yazmasını sağlamak için before özelliği kullanılabilir:

exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onWrite((change, context) => {
      // Only edit data when it is first created.
      if (change.before.exists()) {
        return null;
      }
      // Exit when the data is deleted.
      if (!change.after.exists()) {
        return null;
      }
      // Grab the current value of what was written to the Realtime Database.
      const original = change.after.val();
      console.log('Uppercasing', context.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return change.after.ref.parent.child('uppercase').set(uppercase);
    });