Realtime Database tetikleyicileri


Cloud Functions ile şurada etkinlikleri düzenleyebilirsiniz: İstemci kodunun güncellenmesine gerek kalmadan Firebase Realtime Database. Cloud Functions, tam yönetici erişimiyle Realtime Database işlemi çalıştırmanıza olanak tanır ve Realtime Database üzerinde yapılan her değişikliğin işlenmesini sağlar. ayrı ayrı düzenleyebilirsiniz. Firebase Realtime Database değişikliklerini DataSnapshot veya Admin SDK üzerinden yapabilirsiniz.

Tipik bir yaşam döngüsünde Firebase Realtime Database işlevi aşağıdakileri yapar:

  1. Belirli bir Realtime Database konumunda yapılan değişiklikleri bekler.
  2. Bir etkinlik gerçekleştiğinde tetiklenir ve görevlerini gerçekleştirir (Cloud Functions ile neler yapabilirim? başlıklı makaleyi inceleyin. kullanım alanı örnekleri için).
  3. Belirtilen dokümanda 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. Alıcı: işlevin ne zaman tetikleneceğini kontrol edin, etkinlik işleyicilerden birini belirtin ve etkinlikleri dinleyacağı Realtime Database yolunu belirtin.

Etkinlik işleyiciyi ayarlama

İşlevler, Realtime Database etkinliklerini iki kesinlik düzeyinde işlemenizi sağlar; sadece içerik oluşturma, güncelleme ve veya bir yoldaki herhangi bir değişikliği dinleyebilirsiniz. Cloud Functions, Realtime Database için aşağıdaki etkinlik işleyicileri destekler:

  • Realtime Database alanında veri oluşturulduğunda, güncellendiğinde veya silindiğinde tetiklenen onWrite().
  • Realtime Database içinde yeni veri oluşturulduğunda tetiklenen onCreate().
  • onUpdate(), Realtime Database içinde veriler güncellendiğinde tetiklenir .
  • Realtime Database ürününden veriler silindiğinde tetiklenen onDelete() .

Örneği ve yolu belirtin

İşlevinizin ne zaman ve nerede tetikleneceğini kontrol etmek için ref(path) çağrısı yapın bir yol belirtin ve isteğe bağlı olarak bir Realtime Database örneği belirtin instance('INSTANCE_NAME') ile. Bir örnek belirtmezseniz işlev, Firebase projesinin 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ğindeki belirli bir yoldaki yazma işlemlerini gerçekleştirecek şekilde yönlendirir. Yol özellikleri, bir yola dokunan tüm yazmalarla eşleşir, yazmalar dahil daha iyi olur. Yolun belirli bir /foo/bar olarak fonksiyonunuz için şu 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 durumda, veritabanınızın köküne yakın tek bir işlev 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öşeli parantezle çevreleyerek joker karakter olarak belirtebilirsiniz; ref('foo/{bar}'), /foo'un herhangi bir alt öğesiyle 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

Joker karakter içeren yollar, tek bir yazma işleminden birden fazla etkinliği eşleştirebilir. Ek

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

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

Etkinlik verilerini işleme

Realtime Database etkinliği işlenirken döndürülen veri nesnesi bir DataSnapshot olur. onWrite veya onUpdate etkinlikleri için ilk parametre, tetikleyici etkinlikten önceki ve sonraki veri durumunu temsil eden iki anlık görüntü içeren bir Change nesnesi olur. onCreate ve onDelete etkinlikleri 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ü alır, bu konumdaki dizeyi büyük harfe dönüştürür ve değiştirilmiş 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

Kaynak: EventContext.auth ve EventContext.authType, erişebilirsiniz etkinliği tetikleyen kullanıcıya ait izinler dahil olmak üzere bir işlev olarak tanımlanır. Bu, güvenlik kurallarını zorunlu kılmak için yararlı olabilir. Böylece işlevinizin, kullanıcının izin düzeyine göre farklı işlemleri tamamlamasına izin verebilirsiniz:

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 "başkasının kimliğini kullanabilir kullanıcı kullanıcı adına yazma işlemleri gerçekleştirebilir. 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ğer okunuyor

Change nesnesi bir before Realtime Database önce unutmayın. before mülkü, tüm yöntemlerin (örneğin, val() ve exists()) önceki değere atıfta bulunduğ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 mülk, temsil eden başka bir DataSnapshot etkinlikten sonra verilerin durumunu gösterir.

Örneğin, before mülkü, işlevin metni yalnızca ilk oluşturulduğunda büyük harf kullanması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);
    });