Praca z listami danych w sieci

Uzyskaj odniesienie do bazy danych

Aby odczytywać lub zapisywać dane z bazy danych, potrzebujesz instancji firebase.database.Reference :

Web version 9

import { getDatabase } from "firebase/database";

const database = getDatabase();

Web version 8

var database = firebase.database();

Listy do czytania i pisania

Dołącz do listy danych

Użyj metody push() , aby dołączyć dane do listy w aplikacjach obsługujących wielu użytkowników. Metoda push() generuje unikalny klucz za każdym razem, gdy do określonego odniesienia Firebase dodawany jest nowy element potomny. Korzystając z tych automatycznie generowanych kluczy dla każdego nowego elementu na liście, kilku klientów może dodawać elementy podrzędne do tej samej lokalizacji w tym samym czasie bez konfliktów zapisu. Unikalny klucz generowany przez push() jest oparty na znaczniku czasu, więc elementy listy są automatycznie uporządkowane chronologicznie.

Możesz użyć odwołania do nowych danych zwróconych przez metodę push() , aby uzyskać wartość automatycznie wygenerowanego klucza lub zestawu danych dziecka. Właściwość .key odwołania push() zawiera automatycznie wygenerowany klucz.

Możesz użyć tych automatycznie generowanych kluczy, aby uprościć spłaszczanie struktury danych. Aby uzyskać więcej informacji, zobacz przykład rozkładania danych .

Na przykład push() może zostać użyte do dodania nowego posta do listy postów w aplikacji społecznościowej:

Web version 9

import { getDatabase, ref, push, set } from "firebase/database";

// Create a new post reference with an auto-generated id
const db = getDatabase();
const postListRef = ref(db, 'posts');
const newPostRef = push(postListRef);
set(newPostRef, {
    // ...
});

Web version 8

// Create a new post reference with an auto-generated id
var postListRef = firebase.database().ref('posts');
var newPostRef = postListRef.push();
newPostRef.set({
    // ...
});

Słuchaj wydarzeń dla dzieci

Zdarzenia podrzędne są wyzwalane w odpowiedzi na określone operacje, które mają miejsce na elementach podrzędnych węzła z operacji, takich jak dodanie nowego elementu podrzędnego za pomocą metody push() lub zaktualizowanie elementu podrzędnego za pomocą metody update() .

Wydarzenie Typowe użycie
child_added Pobieraj listy elementów lub słuchaj dodatków do listy elementów. To zdarzenie jest wyzwalane raz dla każdego istniejącego elementu podrzędnego, a następnie ponownie za każdym razem, gdy do określonej ścieżki zostanie dodany nowy element podrzędny. Odbiornik otrzymuje migawkę zawierającą dane nowego dziecka.
child_changed Słuchaj zmian pozycji na liście. To zdarzenie jest wyzwalane za każdym razem, gdy modyfikowany jest węzeł podrzędny. Obejmuje to wszelkie modyfikacje potomków węzła podrzędnego. Migawka przekazana do detektora zdarzeń zawiera zaktualizowane dane elementu podrzędnego.
child_removed Słuchaj, czy elementy są usuwane z listy. To zdarzenie jest wyzwalane po usunięciu bezpośredniego elementu podrzędnego. Migawka przekazana do bloku wywołania zwrotnego zawiera dane usuniętego elementu podrzędnego.
child_moved Słuchaj zmian kolejności elementów na uporządkowanej liście. Zdarzenia child_moved zawsze następują po zdarzeniu child_changed , które spowodowało zmianę kolejności elementu (na podstawie bieżącej metody zamawiania według).

Każde z nich razem może być przydatne do nasłuchiwania zmian w określonym węźle w bazie danych. Na przykład aplikacja do blogowania społecznościowego może wykorzystywać te metody razem do monitorowania aktywności w komentarzach do posta, jak pokazano poniżej:

Web version 9

import { getDatabase, ref, onChildAdded, onChildChanged, onChildRemoved } from "firebase/database";

const db = getDatabase();
const commentsRef = ref(db, 'post-comments/' + postId);
onChildAdded(commentsRef, (data) => {
  addCommentElement(postElement, data.key, data.val().text, data.val().author);
});

onChildChanged(commentsRef, (data) => {
  setCommentValues(postElement, data.key, data.val().text, data.val().author);
});

onChildRemoved(commentsRef, (data) => {
  deleteComment(postElement, data.key);
});

Web version 8

var commentsRef = firebase.database().ref('post-comments/' + postId);
commentsRef.on('child_added', (data) => {
  addCommentElement(postElement, data.key, data.val().text, data.val().author);
});

commentsRef.on('child_changed', (data) => {
  setCommentValues(postElement, data.key, data.val().text, data.val().author);
});

commentsRef.on('child_removed', (data) => {
  deleteComment(postElement, data.key);
});

Słuchaj wartościowych wydarzeń

Podczas gdy nasłuchiwanie zdarzeń podrzędnych jest zalecanym sposobem odczytywania list danych, istnieją sytuacje, w których nasłuchiwanie zdarzeń wartości w odwołaniu do listy jest przydatne.

Dołączenie obserwatora value do listy danych zwróci całą listę danych jako pojedynczą migawkę, którą można następnie zapętlić, aby uzyskać dostęp do poszczególnych elementów podrzędnych.

Nawet jeśli istnieje tylko jedno dopasowanie do zapytania, migawka nadal jest listą; zawiera tylko jeden element. Aby uzyskać dostęp do elementu, musisz zapętlić wynik:

Web version 9

import { getDatabase, ref, onValue } from "firebase/database";

const db = getDatabase();
const dbRef = ref(db, '/a/b/c');

onValue(dbRef, (snapshot) => {
  snapshot.forEach((childSnapshot) => {
    const childKey = childSnapshot.key;
    const childData = childSnapshot.val();
    // ...
  });
}, {
  onlyOnce: true
});

Web version 8

ref.once('value', (snapshot) => {
  snapshot.forEach((childSnapshot) => {
    var childKey = childSnapshot.key;
    var childData = childSnapshot.val();
    // ...
  });
});

Ten wzorzec może być przydatny, gdy chcesz pobrać wszystkie elementy podrzędne listy w jednej operacji, zamiast nasłuchiwać dodatkowych zdarzeń dodanych podrzędnych.

Sortowanie i filtrowanie danych

Możesz użyć klasy Query do bazy danych czasu rzeczywistego, aby pobrać dane posortowane według klucza, wartości lub wartości elementu podrzędnego. Możesz także filtrować posortowany wynik do określonej liczby wyników lub zakresu kluczy lub wartości.

Sortuj dane

Aby pobrać posortowane dane, zacznij od określenia jednej z metod porządkowania w celu określenia kolejności wyników:

metoda Stosowanie
orderByChild() Uporządkuj wyniki według wartości określonego klucza podrzędnego lub zagnieżdżonej ścieżki podrzędnej.
orderByKey() Uporządkuj wyniki według kluczy potomnych.
orderByValue() Uporządkuj wyniki według wartości podrzędnych.

W danym momencie możesz użyć tylko jednej metody zamawiania według. Wielokrotne wywołanie metody sortowania według w tym samym zapytaniu spowoduje zgłoszenie błędu.

Poniższy przykład pokazuje, jak można pobrać listę najlepszych postów użytkownika posortowaną według liczby gwiazdek:

Web version 9

import { getDatabase, ref, query, orderByChild } from "firebase/database";
import { getAuth } from "firebase/auth";

const db = getDatabase();
const auth = getAuth();

const myUserId = auth.currentUser.uid;
const topUserPostsRef = query(ref(db, 'user-posts/' + myUserId), orderByChild('starCount'));

Web version 8

var myUserId = firebase.auth().currentUser.uid;
var topUserPostsRef = firebase.database().ref('user-posts/' + myUserId).orderByChild('starCount');

Definiuje to zapytanie, które w połączeniu z detektorem podrzędnym synchronizuje klienta z postami użytkownika ze ścieżki w bazie danych na podstawie jego identyfikatora użytkownika, uporządkowanego według liczby gwiazdek otrzymanych przez każdy post. Ta technika używania identyfikatorów jako kluczy indeksowych nazywana jest rozrzutem danych. Więcej informacji na ten temat można znaleźć w artykule Struktura bazy danych .

Wywołanie metody orderByChild() określa klucz podrzędny, według którego mają zostać uporządkowane wyniki. W takim przypadku posty są sortowane według wartości odpowiadającego im elementu podrzędnego "starCount" . Zapytania można również uporządkować według zagnieżdżonych elementów podrzędnych, jeśli masz dane, które wyglądają tak:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

W takim przypadku możemy uporządkować nasze elementy listy według wartości zagnieżdżonych w kluczu metrics , określając ścieżkę względną do zagnieżdżonego elementu podrzędnego w naszym wywołaniu orderByChild() .

Web version 9

import { getDatabase, ref, query, orderByChild } from "firebase/database";

const db = getDatabase();
const mostViewedPosts = query(ref(db, 'posts'), orderByChild('metrics/views'));

Web version 8

var mostViewedPosts = firebase.database().ref('posts').orderByChild('metrics/views');

Aby uzyskać więcej informacji na temat porządkowania innych typów danych, zobacz Jak uporządkowane są dane zapytania .

Filtrowanie danych

Aby filtrować dane, podczas konstruowania zapytania można połączyć dowolną metodę limitu lub zakresu z metodą porządkowania według.

metoda Stosowanie
limitToFirst() Ustawia maksymalną liczbę elementów do zwrócenia od początku uporządkowanej listy wyników.
limitToLast() Ustawia maksymalną liczbę elementów do zwrócenia z końca uporządkowanej listy wyników.
startAt() Zwróć elementy większe lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody porządkowania.
startAfter() Zwróć elementy większe niż określony klucz lub wartość w zależności od wybranej metody zamawiania.
endAt() Zwracaj przedmioty mniejsze lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody zamawiania.
endBefore() Zwracaj pozycje mniejsze niż określony klucz lub wartość w zależności od wybranej metody zamawiania.
equalTo() Zwróć elementy równe określonemu kluczowi lub wartości, w zależności od wybranej metody zamawiania.

W przeciwieństwie do metod sortowania według, można łączyć wiele funkcji limitów lub zakresów. Można na przykład połączyć metody startAt() i endAt() w celu ograniczenia wyników do określonego zakresu wartości.

Ogranicz liczbę wyników

Za pomocą metod limitToFirst() i limitToLast() można ustawić maksymalną liczbę dzieci do zsynchronizowania dla danego zdarzenia. Na przykład, jeśli użyjesz limitToFirst() do ustawienia limitu 100, początkowo otrzymasz tylko do 100 zdarzeń child_added . Jeśli masz mniej niż 100 elementów przechowywanych w bazie danych Firebase, zdarzenie child_added jest uruchamiane dla każdego elementu.

Gdy elementy się zmieniają, otrzymujesz zdarzenia child_added dla elementów, które wprowadzają zapytanie, i zdarzenia child_removed dla elementów, które z niego wypadają, dzięki czemu łączna liczba pozostaje na poziomie 100.

Poniższy przykład pokazuje, jak przykładowa aplikacja do blogowania definiuje zapytanie w celu pobrania listy 100 najnowszych postów wszystkich użytkowników:

Web version 9

import { getDatabase, ref, query, limitToLast } from "firebase/database";

const db = getDatabase();
const recentPostsRef = query(ref(db, 'posts'), limitToLast(100));

Web version 8

var recentPostsRef = firebase.database().ref('posts').limitToLast(100);

Ten przykład definiuje tylko zapytanie, aby faktycznie zsynchronizować dane, musi mieć dołączony odbiornik .

Filtruj według klucza lub wartości

startAt() , startAfter() , endAt() , endBefore() i equalTo() można używać do wybierania dowolnych punktów początkowych, końcowych i równoważnych dla zapytań. Może to być przydatne do dzielenia danych na strony lub znajdowania elementów z elementami podrzędnymi, które mają określoną wartość.

Jak uporządkowane są dane zapytania

W tej sekcji wyjaśniono, w jaki sposób dane są sortowane według każdej z metod sortowania według w klasie Query .

orderByChild

Podczas korzystania z orderByChild() dane zawierające określony klucz podrzędny są uporządkowane w następujący sposób:

  1. Dzieci z wartością null dla określonego klucza podrzędnego są na pierwszym miejscu.
  2. Dzieci z wartością false dla określonego klucza potomnego są następne. Jeśli wiele elementów podrzędnych ma wartość false , są one sortowane leksykograficznie według klucza.
  3. Dzieci z wartością true dla określonego klucza podrzędnego są następne. Jeśli wiele elementów podrzędnych ma wartość true , są one sortowane leksykograficznie według klucza.
  4. Następne są dzieci z wartością liczbową, posortowane rosnąco. Jeśli wiele elementów podrzędnych ma tę samą wartość liczbową dla określonego węzła podrzędnego, są one sortowane według klucza.
  5. Ciągi występują po liczbach i są sortowane leksykograficznie w porządku rosnącym. Jeśli wiele elementów podrzędnych ma tę samą wartość dla określonego węzła podrzędnego, są one uporządkowane leksykograficznie według klucza.
  6. Obiekty są na końcu i są sortowane leksykograficznie według klucza w porządku rosnącym.

orderByKey

Gdy używasz orderByKey() do sortowania danych, dane są zwracane w porządku rosnącym według klucza.

  1. Dzieci z kluczem, który można przeanalizować jako 32-bitową liczbę całkowitą, są pierwsze, posortowane w porządku rosnącym.
  2. Dzieci z wartością ciągu jako kluczem są następne, posortowane leksykograficznie w porządku rosnącym.

orderByValue

Podczas korzystania z orderByValue() elementy podrzędne są sortowane według ich wartości. Kryteria porządkowania są takie same jak w przypadku orderByChild() , z wyjątkiem tego, że zamiast wartości określonego klucza podrzędnego używana jest wartość węzła.

Odłącz słuchaczy

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

Możesz usunąć pojedynczego słuchacza, przekazując go jako parametr do off() . Wywołanie off() w lokalizacji bez argumentów usuwa wszystkie detektory w tej lokalizacji.

Wywołanie funkcji off() na odbiorniku nadrzędnym nie usuwa automatycznie detektorów zarejestrowanych w jego węzłach podrzędnych; off() musi być również wywołana na wszystkich słuchaczach potomnych, aby usunąć wywołanie zwrotne.

Następne kroki