Gerçek Zamanlı Veritabanı tetikleyicileri


Cloud Functions ile Firebase Gerçek Zamanlı Veritabanındaki olayları istemci kodunu güncellemeye gerek kalmadan yönetebilirsiniz. Bulut İşlevleri, Gerçek Zamanlı Veritabanı işlemlerini tam yönetim 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 Gerçek Zamanlı Veritabanı değişikliklerini DataSnapshot veya Admin SDK aracılığıyla yapabilirsiniz.

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

  1. Belirli bir Gerçek Zamanlı Veritabanı konumunda değişiklik yapılmasını bekler.
  2. Bir olay meydana geldiğinde tetiklenir ve görevlerini gerçekleştirir (kullanım örnekleri için bkz . Bulut İşlevleri ile neler yapabilirim? ).
  3. Belirtilen belgede depolanan verilerin anlık görüntüsünü içeren bir veri nesnesini 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şleyicilerden birini belirtin ve olayları dinleyeceği Gerçek Zamanlı Veritabanı yolunu belirtin.

Olay işleyicisini ayarlayın

İşlevler, Gerçek Zamanlı Veritabanı olaylarını iki düzeyde spesifiklikle yönetmenizi sağlar; yalnızca oluşturma, güncelleme veya silme olaylarını özel olarak dinleyebilir veya bir yoldaki herhangi bir tür değişikliği dinleyebilirsiniz. Cloud Functions, Gerçek Zamanlı Veritabanı için şu olay işleyicilerini destekler:

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

Örneği ve yolu belirtin

İşlevinizin ne zaman ve nerede tetikleneceğini kontrol etmek için ref(path) çağırarak bir yol belirtin ve isteğe bağlı olarak instance('INSTANCE_NAME') ile bir Gerçek Zamanlı Veritabanı ö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 Realtime Database örneği içinde belirli bir yoldaki yazma işlemlerini gerçekleştirecek şekilde yönlendirir. Yol özellikleri, bir yola dokunan tüm yazma işlemleriyle (bunun altında herhangi bir yerde gerçekleşen yazma işlemleri de dahil) 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. Etkinlik verileri büyükse, 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 yalnızca mümkün olan en derin düzeydeki verileri isteyin.

Bir yol bileşenini küme parantezleriyle çevreleyerek joker karakter olarak belirtebilirsiniz; ref('foo/{bar}') /foo öğesinin herhangi bir alt öğesiyle eşleşir. Bu joker karakter yolu bileşenlerinin değerleri, fonksiyonunuzun EventContext.params nesnesinde mevcuttur. Bu örnekte değer context.params.bar olarak mevcuttur.

Joker karakterler içeren yollar, tek bir yazma işleminde birden fazla olayı eşleştirebilir. Bir ekleme

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

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

Etkinlik verilerini işleme

Bir Gerçek Zamanlı Veritabanı olayını işlerken döndürülen veri nesnesi bir DataSnapshot olur. 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 , bir işlevi tetikleyen kullanıcının izinleri de dahil olmak üzere kullanıcı bilgilerine erişebilirsiniz. Bu, güvenlik kurallarının uygulanmasında yararlı olabilir ve işlevinizin, kullanıcının izin düzeyine göre farklı işlemleri tamamlamasına olanak tanır:

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ğerin okunması

Change nesnesi, olaydan önce Realtime Database'e nelerin kaydedildiğini incelemenize olanak tanıyan 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, işlevin metni ilk oluşturulduğunda 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);
    });