Realtime Database tetikleyicileri


Cloud Functions ile Firebase Realtime Database içindeki etkinlikleri istemci kodunu güncellemenize gerek kalmadan yönetebilirsiniz. Cloud Functions, Realtime Database işlemlerini tam yönetim ayrıcalıklarıyla çalıştırmanıza olanak tanır ve Realtime Database'de yapılan her değişikliğin ayrı ayrı işlenmesini sağlar. Firebase Realtime Database değişiklikleri DataSnapshot veya Admin SDK üzerinden yapabilirsiniz.

Tipik bir yaşam döngüsünde, Firebase Realtime Database işlevi şunları yapar:

  1. Belirli bir Realtime Database konumunda değişiklik yapılmasını bekler.
  2. Bir etkinlik gerçekleştiğinde tetiklenir ve görevlerini yerine getirir (bkz. Cloud Functions ile neler yapabilirim?). kullanım alanı örnekleri için).
  3. Belirtilen belgede depolanan verilerin anlık görüntüsünü içeren bir veri nesnesi alır.

Realtime Database işlevini tetikleme

functions.database ile Realtime Database etkinlikleri için yeni işlevler oluşturun. İşlevin ne zaman tetikleneceğini kontrol etmek için etkinlik işleyicilerden birini ve etkinlikleri dinleyeceği Realtime Database yolunu belirtin.

Etkinlik işleyiciyi ayarlama

İşlevler, Realtime Database etkinliklerini iki özgüllük düzeyinde işlemenize olanak tanır. Yalnızca oluşturma, güncelleme veya silme etkinliklerini dinleyebilir ya da bir yolda yapılan her türlü değişikliği dinleyebilirsiniz. Cloud Functions, Realtime Database için şu etkinlik işleyicileri destekler:

  • onWrite(): Realtime Database'de veri oluşturulduğunda, güncellendiğinde veya silindiğinde tetiklenir.
  • onCreate(), Realtime Database içinde yeni veriler oluşturulduğunda tetiklenir.
  • onUpdate(): Realtime Database içinde veriler güncellendiğinde tetiklenir .
  • onDelete(), Realtime Database verileri silindiğinde tetiklenir .

Örneği ve yolu belirtin

İşlevinizin ne zaman ve nerede tetikleneceğini kontrol etmek için ref(path) işlevini çağırarak bir yol belirtin 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 Realtime Database örneğine dağıtılır. Örneğin:

  • Varsayılan Realtime Database ö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çindeki belirli bir yolda yazma işlemlerini gerçekleştirecek şekilde yönlendirir. Yol belirtimleri, yolun herhangi bir bölümüne dokunan tüm yazma işlemlerini (yolun altında gerçekleşen yazma işlemleri dahil) eşleştirir. İşlevinizin yolunu /foo/bar olarak ayarlarsanız aşağıdaki konumların her ikisindeki etkinliklerle eşleşir:

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

Her iki durumda da Firebase, etkinliğin /foo/bar tarihinde gerçekleştiğini yorumlar ve etkinlik verileri, /foo/bar tarihindeki eski ve yeni verileri içerir. Etkinlik verileri büyük olabilir. Bu nedenle, veritabanınızın kökünün yakınında tek bir işlev kullanmak yerine daha derin yollarda birden fazla işlev kullanmayı düşünebilirsiniz. En iyi performans için yalnızca mümkün olan en derin düzeyde veri isteyin.

Bir yol bileşenini küme parantezleriyle çevreleyerek joker karakter olarak belirtebilirsiniz. ref('foo/{bar}'), /foo öğesinin tüm alt öğeleriyle eşleşir. Bu joker karakterli yol bileşenlerinin değerleri, işlevinizin EventContext.params nesnesinde kullanılabilir. Bu örnekte değer, context.params.bar olarak kullanılabilir.

Joker karakter içeren yollar, tek bir yazma işleminden birden fazla etkinlikle eşleşebilir. Şunun eklenmesi:

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

"/foo/{bar}" yoluyla iki kez eşleşir: bir kez "hello": "world" ile, bir kez de "firebase": "functions" ile.

Etkinlik verilerini işleme

Bir Realtime Database etkinliği işlenirken döndürülen veri nesnesi DataSnapshot olur. onWrite veya onUpdate etkinliklerinde ilk parametre, tetikleyici etkinlikten önce ve sonraki veri durumunu temsil eden iki anlık görüntüyü içeren bir Change nesnesidir. onCreate ve onDelete etkinliklerinde, döndürülen veri nesnesi, oluşturulan veya silinen verilerin anlık görüntüsüdür.

Bu örnekte işlev, belirtilen yolun anlık görüntüsünü alır, bu 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'tan bir işlevi tetikleyen kullanıcının izinler de dahil olmak üzere kullanıcı bilgilerine erişebilirsiniz. Bu, güvenlik kurallarını zorunlu kılmak ve işlevinizin kullanıcının izin düzeyine göre farklı işlemler gerçekleştirmesine olanak tanımak için yararlı olabilir:

const functions = require('firebase-functions/v1');
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, kullanıcı kimlik doğrulama bilgilerinden yararlanarak bir kullanıcının "kimliğine bürünebilir" ve kullanıcı adına yazma işlemleri gerçekleştirebilirsiniz. Eşzamanlılık sorunlarını önlemek için uygulama örneğini aşağıdaki şekilde 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 nesnesinde, etkinlikten önce Realtime Database öğesine kaydedilenleri incelemenize olanak tanıyan bir before özelliği bulunur. before özelliği, tüm yöntemlerin (örneğin, val() ve exists()) önceki değeri ifade ettiği bir DataSnapshot döndürür. Yeni değeri, orijinal DataSnapshot özelliğini kullanarak veya after özelliğini okuyarak tekrar okuyabilirsiniz. Herhangi bir Change üzerindeki bu özellik, etkinliğin gerçekleşmesinden sonra verilerin durumunu temsil eden başka bir DataSnapshot'dir.

Örneğin, before özelliği, işlevin metni yalnızca ilk oluşturulduğunda büyük harfe çevirmesini sağlamak için 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);
    });