Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Wyzwalacze bazy danych czasu rzeczywistego

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Dzięki Cloud Functions możesz obsługiwać zdarzenia w bazie danych czasu rzeczywistego Firebase bez konieczności aktualizowania kodu klienta. Cloud Functions umożliwia uruchamianie operacji w bazie danych czasu rzeczywistego z pełnymi uprawnieniami administracyjnymi i gwarantuje, że każda zmiana w bazie danych czasu rzeczywistego jest przetwarzana indywidualnie. Zmiany w Bazie danych czasu rzeczywistego Firebase możesz wprowadzać za pomocą DataSnapshot lub Admin SDK .

W typowym cyklu życia funkcja Bazy danych czasu rzeczywistego Firebase wykonuje następujące czynności:

  1. Czeka na zmiany w określonej lokalizacji bazy danych czasu rzeczywistego.
  2. Wyzwala się, gdy zdarzenie ma miejsce i wykonuje swoje zadania (zobacz Co mogę zrobić z Cloud Functions?, aby zapoznać się z przykładami przypadków użycia).
  3. Odbiera obiekt danych, który zawiera migawkę danych przechowywanych w określonym dokumencie.

Uruchom funkcję bazy danych czasu rzeczywistego

Twórz nowe funkcje dla zdarzeń bazy danych czasu rzeczywistego za pomocą functions.database . Aby kontrolować, kiedy funkcja jest wyzwalana, określ jedną z procedur obsługi zdarzeń i określ ścieżkę do bazy danych czasu rzeczywistego, w której będzie nasłuchiwać zdarzeń.

Ustaw obsługę zdarzeń

Funkcje umożliwiają obsługę zdarzeń bazy danych czasu rzeczywistego na dwóch poziomach szczegółowości; możesz nasłuchiwać tylko dla zdarzeń tworzenia, aktualizacji lub usuwania lub możesz nasłuchiwać jakichkolwiek zmian w ścieżce. Cloud Functions obsługuje te procedury obsługi zdarzeń dla bazy danych czasu rzeczywistego:

  • onWrite() , która jest wyzwalana, gdy dane są tworzone, aktualizowane lub usuwane w bazie danych czasu rzeczywistego.
  • onCreate() , która uruchamia się, gdy nowe dane są tworzone w bazie danych czasu rzeczywistego.
  • onUpdate() , która uruchamia się, gdy dane są aktualizowane w bazie danych czasu rzeczywistego.
  • onDelete() , która uruchamia się, gdy dane są usuwane z bazy danych czasu rzeczywistego .

Określ instancję i ścieżkę

Aby kontrolować, kiedy i gdzie funkcja ma się uruchamiać, wywołaj funkcję ref(path) w celu określenia ścieżki i opcjonalnie określ instancję bazy danych czasu rzeczywistego za pomocą funkcji instance('INSTANCE_NAME') . Jeśli nie określisz instancji, funkcja zostanie wdrożona w domyślnej instancji Bazy danych czasu rzeczywistego dla projektu Firebase. Na przykład:

  • Domyślna instancja bazy danych czasu rzeczywistego: functions.database.ref('/foo/bar')
  • Instancja o nazwie „my-app-db-2”: functions.database.instance('my-app-db-2').ref('/foo/bar')

Te metody kierują twoją funkcję do obsługi zapisów w określonej ścieżce w instancji bazy danych czasu rzeczywistego. Specyfikacje ścieżki pasują do wszystkich zapisów, które dotykają ścieżki, w tym zapisów, które mają miejsce gdziekolwiek poniżej. Jeśli ustawisz ścieżkę dla swojej funkcji jako /foo/bar , dopasuje ona zdarzenia w obu tych lokalizacjach:

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

W obu przypadkach Firebase interpretuje, że zdarzenie ma miejsce w /foo/bar , a dane zdarzenia obejmują stare i nowe dane w /foo/bar . Jeśli dane zdarzeń mogą być duże, rozważ użycie wielu funkcji w głębszych ścieżkach zamiast jednej funkcji w pobliżu katalogu głównego bazy danych. Aby uzyskać najlepszą wydajność, żądaj danych tylko na najgłębszym możliwym poziomie.

Możesz określić komponent ścieżki jako symbol wieloznaczny, otaczając go nawiasami klamrowymi; ref('foo/{bar}') dopasowuje dowolne dziecko /foo . Wartości tych składników ścieżki z symbolami wieloznacznymi są dostępne w obiekcie EventContext.params Twojej funkcji. W tym przykładzie wartość jest dostępna jako context.params.bar .

Ścieżki z symbolami wieloznacznymi mogą pasować do wielu zdarzeń z jednego zapisu. Wkładka z

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

dwukrotnie dopasowuje ścieżkę "/foo/{bar}" : raz z "hello": "world" i ponownie z "firebase": "functions" .

Obsługuj dane zdarzeń

Podczas obsługi zdarzenia bazy danych czasu rzeczywistego zwracanym obiektem danych jest DataSnapshot . W przypadku zdarzeń onWrite lub onUpdate pierwszym parametrem jest obiekt Change , który zawiera dwie migawki reprezentujące stan danych przed i po zdarzeniu wyzwalającym. W przypadku zdarzeń onCreate i onDelete zwracany obiekt danych jest migawką utworzonych lub usuniętych danych.

W tym przykładzie funkcja pobiera migawkę dla określonej ścieżki jako snap , konwertuje ciąg w tej lokalizacji na wielkie litery i zapisuje zmodyfikowany ciąg do bazy danych:

// 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);
    });

Dostęp do informacji uwierzytelniających użytkownika

Z EventContext.auth i EventContext.authType można uzyskać dostęp do informacji o użytkowniku, w tym uprawnień, dla użytkownika, który wyzwolił funkcję. Może to być przydatne do egzekwowania reguł bezpieczeństwa, umożliwiając Twojej funkcji wykonywanie różnych operacji w zależności od poziomu uprawnień użytkownika:

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);
      }
    });

Możesz także wykorzystać informacje uwierzytelniające użytkownika, aby „podszywać się” pod użytkownika i wykonywać operacje zapisu w jego imieniu. Pamiętaj, aby usunąć instancję aplikacji, jak pokazano poniżej, aby zapobiec problemom z współbieżnością:

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));
      });
    });

Odczyt poprzedniej wartości

Obiekt Change ma właściwość before , która pozwala sprawdzić, co zostało zapisane w bazie danych czasu rzeczywistego przed zdarzeniem. Właściwość before zwraca obiekt DataSnapshot , w którym wszystkie metody (na przykład val() i exists() ) odwołują się do poprzedniej wartości. Możesz ponownie odczytać nową wartość, używając oryginalnej DataSnapshot lub odczytując właściwość after . Ta właściwość dowolnej Change jest kolejną DataSnapshot reprezentującą stan danych po wystąpieniu zdarzenia.

Na przykład właściwość before może być wykorzystana do upewnienia się, że podczas pierwszego tworzenia funkcji tekst jest pisany tylko wielkimi literami:

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);
    });