Realtime Database tetikleyicileri


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

Tipik bir yaşam döngüsünde bir 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 ve görevlerini yerine getirdiğinde tetiklenir. (Kullanım alanı örnekleri için Cloud Functions ile neler yapabilirim? bölümüne bakın).
  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 belirtin ve etkinlikleri dinleyeceği Realtime Database yolunu belirtin.

Etkinlik işleyiciyi ayarlama

Functions, Realtime Database etkinliklerini iki belirginlik düzeyinde işlemenize olanak tanır. Yalnızca oluşturma, güncelleme veya silme etkinlikleri için veya bir yolda yapılan her tür değişikliği dinleyebilirsiniz. Cloud Functions, Realtime Database için şu etkinlik işleyicilerini destekler:

  • onWrite(), Realtime Database'de veriler oluşturulduğunda, güncellendiğinde veya silindiğinde tetiklenir.
  • Realtime Database'de yeni veriler oluşturulduğunda tetiklenen onCreate().
  • onUpdate(), veriler Realtime Database'de güncellendiğinde tetiklenir .
  • onDelete(), veriler Realtime Database'den silindiğinde tetiklenir .

Örneği ve yolu belirtin

İşlevinizin ne zaman ve nerede tetikleneceğini kontrol etmek amacıyla yol belirtmek için ref(path) çağrısı yapın ve isteğe bağlı olarak instance('INSTANCE_NAME') ile bir Realtime Database örneği belirtin. Örnek belirtmezseniz işlev, Firebase projesi için varsayılan Realtime Database örneğine dağıtım yapar. Ö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çinde belirli bir yoldaki yazma işlemlerini işlemeye yönlendirir. Yol spesifikasyonları, bir yola dokunan tüm yazma işlemleriyle (yolun altında herhangi bir yerde gerçekleşen yazmalar dahil) eşleşir. İşlevinizin yolunu /foo/bar olarak ayarlarsanız şu iki konumdaki etkinliklerle de 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 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 fazla işlev kullanmayı düşünün. En iyi performans için yalnızca mümkün olan en derin düzeyde veri isteyin.

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

Joker karakter içeren yollar tek bir yazma işleminden birden fazla etkinlikle eşleşebilir. Ek

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

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

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, tetikleme etkinliğinden önceki ve sonraki veri durumunu temsil eden iki anlık görüntü içeren Change nesnesidir. onCreate ve onDelete etkinlikleri için döndürülen veri nesnesi, oluşturulan veya silinen verilerin anlık bir görüntüsüdür.

Bu örnekte, işlev belirtilen yol için anlık görüntüyü 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 üzerinden, bir işlevi tetikleyen kullanıcıyla ilgili izinler dahil olmak üzere kullanıcı bilgilerine erişebilirsiniz. Bu, işlevinizin kullanıcının izin düzeyine göre farklı işlemler tamamlamasına olanak tanıyan güvenlik kurallarını zorunlu kılma konusunda faydalı 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ğini kullanmak" 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, etkinlikten ö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 özelliğini kullanarak veya after özelliğini okuyarak yeni değeri tekrar okuyabilirsiniz. Herhangi bir Change üzerindeki bu özellik, etkinlik gerçekleştikten sonra verilerin durumunu temsil eden başka bir DataSnapshot öğesidir.

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