Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Odczytywanie i zapisywanie danych w Internecie

(Opcjonalnie) Twórz prototypy i testuj za pomocą pakietu Firebase Local Emulator Suite

Zanim porozmawiamy o tym, jak Twoja aplikacja odczytuje i zapisuje w bazie danych czasu rzeczywistego, przedstawmy zestaw narzędzi, których możesz użyć do prototypowania i testowania funkcjonalności bazy danych czasu rzeczywistego: Firebase Local Emulator Suite. Jeśli wypróbowujesz różne modele danych, optymalizujesz reguły bezpieczeństwa lub pracujesz nad znalezieniem najbardziej opłacalnego sposobu interakcji z zapleczem, możliwość pracy lokalnie bez wdrażania usług na żywo może być świetnym pomysłem.

Emulator bazy danych czasu rzeczywistego jest częścią pakietu lokalnego emulatora, który umożliwia aplikacji interakcję z zawartością i konfiguracją emulowanej bazy danych, a także opcjonalnie emulowanymi zasobami projektu (funkcje, inne bazy danych i reguły zabezpieczeń). Należy pamiętać, że pakiet Local Emulator Suite nie obsługuje jeszcze emulowanego magazynu w chmurze.

Korzystanie z emulatora bazy danych czasu rzeczywistego obejmuje tylko kilka kroków:

  1. Dodanie wiersza kodu do konfiguracji testowej aplikacji w celu nawiązania połączenia z emulatorem.
  2. firebase emulators:start z katalogu głównego lokalnego projektu firebase emulators:start .
  3. Wykonywanie wywołań z prototypowego kodu aplikacji przy użyciu zestawu SDK platformy bazy danych czasu rzeczywistego jak zwykle lub przy użyciu interfejsu API REST bazy danych czasu rzeczywistego.

Dostępny jest szczegółowy przewodnik dotyczący bazy danych czasu rzeczywistego i funkcji chmury . Powinieneś także rzucić okiem na wprowadzenie do pakietu lokalnego emulatora .

Uzyskaj odniesienie do bazy danych

Aby odczytać lub zapisać dane z bazy danych, potrzebujesz instancji firebase.database.Reference .

var database = firebase.database();

Napisz dane

Ten dokument obejmuje podstawy pobierania danych oraz porządkowanie i filtrowanie danych Firebase.

Dane z Firebase są pobierane przez dołączenie odbiornika asynchronicznego do firebase.database.Reference . Odbiornik jest wyzwalany raz dla początkowego stanu danych i ponownie za każdym razem, gdy dane ulegną zmianie.

Podstawowe operacje zapisu

W przypadku podstawowych operacji zapisu można użyć set() aby zapisać dane w określonym odwołaniu, zastępując wszelkie istniejące dane w tej ścieżce. Na przykład aplikacja do obsługi blogów społecznościowych może dodać użytkownika za pomocą funkcji set() w następujący sposób:

function writeUserData(userId, name, email, imageUrl) {
  firebase.database().ref('users/' + userId).set({
    username: name,
    email: email,
    profile_picture : imageUrl
  });
}

Użycie set() powoduje nadpisanie danych w określonej lokalizacji, w tym wszystkich węzłów podrzędnych.

Czytaj dane

Nasłuchuj wydarzeń wartościowych

Aby odczytać dane na ścieżce i nasłuchiwać zmian, użyj metod on() lub once() metody firebase.database.Reference do obserwowania zdarzeń.

Zdarzenie Typowe użycie
value Przeczytaj i nasłuchuj zmian w całej zawartości ścieżki.

Możesz użyć zdarzenia value , aby odczytać statyczny obraz zawartości w danej ścieżce, tak jak istniała w momencie zdarzenia. Ta metoda jest wyzwalana raz, gdy odbiornik jest dołączony i ponownie za każdym razem, gdy dane, w tym dane podrzędne, ulegają zmianie. Wywołanie zwrotne zdarzenia otrzymuje migawkę zawierającą wszystkie dane w tej lokalizacji, w tym dane podrzędne. Jeśli nie ma danych, migawka zwróci wartość false gdy wywołasz exists() i null gdy wywołasz na niej funkcję val() .

Poniższy przykład ilustruje aplikację do blogowania społecznościowego pobierającą liczbę gwiazdek posta z bazy danych:

var starCountRef = firebase.database().ref('posts/' + postId + '/starCount');
starCountRef.on('value', (snapshot) => {
  const data = snapshot.val();
  updateStarCount(postElement, data);
});

Odbiornik otrzymuje snapshot zawierającą dane w określonej lokalizacji w bazie danych w momencie zdarzenia. Dane z snapshot można pobrać za pomocą metody val() .

Odczytaj dane raz

Odczytaj dane raz za pomocą funkcji get ()

Pakiet SDK jest przeznaczony do zarządzania interakcjami z serwerami baz danych, niezależnie od tego, czy Twoja aplikacja jest online czy offline.

Ogólnie rzecz biorąc, należy używać technik zdarzeń wartości opisanych powyżej, aby odczytywać dane i otrzymywać powiadomienia o aktualizacjach danych z zaplecza. Techniki nasłuchujące zmniejszają użycie i rozliczenia oraz są zoptymalizowane, aby zapewnić użytkownikom jak najlepsze wrażenia podczas przechodzenia do trybu online i offline.

Jeśli potrzebujesz danych tylko raz, możesz użyć funkcji get() aby uzyskać migawkę danych z bazy danych. Jeśli z jakiegoś powodu get() nie może zwrócić wartości serwera, klient sonduje lokalną pamięć podręczną i zwróci błąd, jeśli wartość nadal nie zostanie znaleziona.

Niepotrzebne użycie metody get() może zwiększyć wykorzystanie przepustowości i doprowadzić do utraty wydajności, której można zapobiec, używając odbiornika czasu rzeczywistego, jak pokazano powyżej.

database.child("users").child(userId).get().then(function(snapshot) {
  if (snapshot.exists()) {
    console.log(snapshot.val());
  }
  else {
    console.log("No data available");
  }
}).catch(function(error) {
  console.error(error);
});

Odczytaj dane raz z obserwatorem

W niektórych przypadkach możesz chcieć, aby wartość z lokalnej pamięci podręcznej została zwrócona natychmiast, zamiast sprawdzania zaktualizowanej wartości na serwerze. W takich przypadkach możesz użyć funkcji once() aby natychmiast pobrać dane z lokalnej pamięci podręcznej dysku.

Jest to przydatne w przypadku danych, które trzeba załadować tylko raz i nie powinny się często zmieniać lub wymagają aktywnego nasłuchiwania. Na przykład aplikacja do blogowania w poprzednich przykładach używa tej metody do ładowania profilu użytkownika, gdy zaczyna on tworzyć nowy post:

var userId = firebase.auth().currentUser.uid;
return firebase.database().ref('/users/' + userId).once('value').then((snapshot) => {
  var username = (snapshot.val() && snapshot.val().username) || 'Anonymous';
  // ...
});

Aktualizacja lub usuwanie danych

Zaktualizuj określone pola

Aby jednocześnie pisać do określonych elementów podrzędnych węzła bez nadpisywania innych węzłów podrzędnych, użyj metody update() .

W przypadku wywołania metody update() można zaktualizować wartości podrzędne niższego poziomu, określając ścieżkę do klucza. Jeśli dane są przechowywane w wielu lokalizacjach w celu lepszego skalowania, możesz zaktualizować wszystkie wystąpienia tych danych za pomocą rozpowszechniania danych .

Na przykład aplikacja do obsługi blogów społecznościowych może utworzyć wpis i jednocześnie zaktualizować go do kanału ostatniej aktywności i kanału aktywności użytkownika publikującego za pomocą następującego kodu:

function writeNewPost(uid, username, picture, title, body) {
  // A post entry.
  var postData = {
    author: username,
    uid: uid,
    body: body,
    title: title,
    starCount: 0,
    authorPic: picture
  };

  // Get a key for a new Post.
  var newPostKey = firebase.database().ref().child('posts').push().key;

  // Write the new post's data simultaneously in the posts list and the user's post list.
  var updates = {};
  updates['/posts/' + newPostKey] = postData;
  updates['/user-posts/' + uid + '/' + newPostKey] = postData;

  return firebase.database().ref().update(updates);
}

W tym przykładzie funkcja push() służy do tworzenia wiadomości w węźle zawierającej wiadomości dla wszystkich użytkowników w /posts/$postid i jednoczesnego pobierania klucza. Klucz może następnie zostać użyty do utworzenia drugiego wpisu w postach użytkownika pod adresem /user-posts/$userid/$postid .

Korzystając z tych ścieżek, można wykonywać jednoczesne aktualizacje w wielu lokalizacjach w drzewie JSON za pomocą jednego wywołania funkcji update() , na przykład w tym przykładzie, w jaki sposób tworzy nowy wpis w obu lokalizacjach. Jednoczesne aktualizacje wykonane w ten sposób są atomowe: albo wszystkie aktualizacje się powiodły, albo wszystkie się nie powiodły.

Dodaj oddzwonienie dotyczące zakończenia

Jeśli chcesz wiedzieć, kiedy Twoje dane zostały zatwierdzone, możesz dodać wywołanie zwrotne zakończenia. Zarówno set() i update() pobierają opcjonalne wywołanie zwrotne zakończenia, które jest wywoływane po zatwierdzeniu zapisu w bazie danych. Jeśli wywołanie nie powiodło się, wywołanie zwrotne jest przekazywane do obiektu błędu wskazującego przyczynę niepowodzenia.

firebase.database().ref('users/' + userId).set({
  username: name,
  email: email,
  profile_picture : imageUrl
}, (error) => {
  if (error) {
    // The write failed...
  } else {
    // Data saved successfully!
  }
});

Usunąć dane

Najprostszym sposobem usunięcia danych jest wywołanie metody remove() w odniesieniu do lokalizacji tych danych.

Możesz również usunąć, określając null jako wartość dla innej operacji zapisu, takiej jak set() lub update() . Możesz użyć tej techniki z update() aby usunąć wiele elementów podrzędnych w jednym wywołaniu interfejsu API.

Otrzymaj Promise

Aby dowiedzieć się, kiedy Twoje dane zostaną przekazane na serwer bazy danych czasu rzeczywistego Firebase, możesz skorzystać z Promise . Zarówno set() i update() mogą zwracać Promise której możesz użyć, aby wiedzieć, kiedy zapis zostanie zatwierdzony w bazie danych.

Odłącz słuchaczy

Wywołania zwrotne są usuwane przez wywołanie metody off() w odwołaniu do bazy danych Firebase.

Możesz usunąć pojedynczy detektor, przekazując go jako parametr do funkcji off() . Wywołanie funkcji off() w lokalizacji bez argumentów powoduje usunięcie wszystkich detektorów w tej lokalizacji.

Wywołanie off() na odbiorniku nadrzędnym nie usuwa automatycznie detektorów zarejestrowanych w jego węzłach potomnych; Aby usunąć wywołanie zwrotne, należy również wywołać funkcję off() we wszystkich odbiornikach podrzędnych.

Zapisz dane jako transakcje

Podczas pracy z danymi, które mogą zostać uszkodzone przez równoczesne modyfikacje, takie jak liczniki przyrostowe, można użyć operacji transakcji . Możesz nadać tej operacji funkcję aktualizacji i opcjonalne wywołanie zwrotne zakończenia. Funkcja aktualizacji przyjmuje bieżący stan danych jako argument i zwraca nowy żądany stan, który chcesz zapisać. Jeśli inny klient zapisuje do lokalizacji, zanim nowa wartość zostanie pomyślnie zapisana, funkcja aktualizacji jest wywoływana ponownie z nową bieżącą wartością, a zapis jest ponawiany.

Na przykład w przykładowej aplikacji do obsługi blogów społecznościowych możesz zezwolić użytkownikom na oznaczanie postów gwiazdką i usuwanie ich oznaczeń oraz śledzenie liczby gwiazdek, które otrzymał post w następujący sposób:

function toggleStar(postRef, uid) {
  postRef.transaction((post) => {
    if (post) {
      if (post.stars && post.stars[uid]) {
        post.starCount--;
        post.stars[uid] = null;
      } else {
        post.starCount++;
        if (!post.stars) {
          post.stars = {};
        }
        post.stars[uid] = true;
      }
    }
    return post;
  });
}

Korzystanie z transakcji zapobiega błędnemu liczeniu gwiazdek, jeśli wielu użytkowników oznaczyło ten sam post w tym samym czasie lub klient miał nieaktualne dane. Jeśli transakcja zostanie odrzucona, serwer zwraca bieżącą wartość klientowi, który ponownie uruchamia transakcję ze zaktualizowaną wartością. Powtarza się do momentu zaakceptowania transakcji lub przerwania transakcji.

Pracuj z danymi w trybie offline

Jeśli klient utraci połączenie sieciowe, Twoja aplikacja będzie nadal działać poprawnie.

Każdy klient podłączony do bazy danych Firebase utrzymuje własną wewnętrzną wersję wszystkich aktywnych danych. Kiedy dane są zapisywane, są najpierw zapisywane w tej wersji lokalnej. Następnie klient Firebase synchronizuje te dane ze zdalnymi serwerami baz danych i innymi klientami na zasadzie „najlepszych starań”.

W rezultacie wszystkie zapisy do bazy danych wyzwalają lokalne zdarzenia natychmiast, zanim jakiekolwiek dane zostaną zapisane na serwerze. Oznacza to, że Twoja aplikacja będzie reagować niezależnie od opóźnień w sieci lub łączności.

Po przywróceniu łączności aplikacja otrzymuje odpowiedni zestaw zdarzeń, dzięki czemu klient synchronizuje się z bieżącym stanem serwera, bez konieczności pisania kodu niestandardowego.

Więcej informacji o zachowaniu w trybie offline znajdziesz w artykule Dowiedz się więcej o możliwościach online i offline .

Następne kroki