Veritabanı Tetikleyicileri

Cloud Functions ile, istemci kodunu güncellemeye gerek kalmadan Firebase Realtime Database'deki olayları 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 Realtime Database işlevi aşağıdakileri yapar:

  1. Belirli bir Gerçek Zamanlı Veritabanı konumundaki değişiklikleri bekler.
  2. Bir olay meydana geldiğinde ve görevlerini yerine getirdiğinde tetiklenir (kullanım ö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.

Gerçek Zamanlı Veritabanı işlevini tetikleyin

Functions.database ile Realtime Database olayları için yeni functions.database 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şleyicisini ayarlayın

İşlevler, Gerçek Zamanlı Veritabanı olaylarını iki özgüllük düzeyinde işlemenize olanak tanır; özel olarak yalnızca oluşturma, güncelleme veya silme olaylarını dinleyebilir veya herhangi bir yol değişikliğini 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() .
  • Gerçek Zamanlı Veritabanından veriler silindiğinde tetiklenen onDelete() .

Örneği ve yolu belirtin

İşlevinizin ne zaman ve nerede tetikleneceğini kontrol etmek için, bir yol belirtmek üzere ref(path) çağırın 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ğinde belirli bir yoldaki yazmaları işlemeye yönlendirir. Yol özellikleri, bir yola dokunan tüm yazma işlemleriyle eşleşir, bunun altında herhangi bir yerde gerçekleşen yazma işlemleri de dahil. İşlevinizin yolunu /foo/bar olarak ayarlarsanız, şu 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 konumunda gerçekleştiğini yorumlar ve olay verileri, /foo/bar eski ve yeni verileri içerir. 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 yalnızca mümkün olan en derin düzeyde veri isteyin.

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

Joker karakterli yollar, tek bir yazma işleminden birden çok olayla eşleşebilir. 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.

Olay verilerini işle

Bir Gerçek Zamanlı Veritabanı olayı işlenirken 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 yolun anlık görüntüsünü snap olarak 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 , bir işlevi tetikleyen kullanıcı için izinler de dahil olmak üzere kullanıcı bilgilerine erişebilirsiniz. Bu, güvenlik kurallarını uygulamak için 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ğeri okuma

Change nesnesinin, olaydan önce Gerçek Zamanlı Veritabanına nelerin kaydedildiğini incelemenizi sağlayan bir before özelliği vardır. 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, before özelliği, işlevin ilk oluşturulduğunda metni yalnızca 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);
    });