Praca z listami danych w sieci

Uzyskaj odniesienie do bazy danych

Aby odczytać lub zapisać 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();

Czytanie i pisanie list

Dołącz do listy danych

Użyj metody push() , aby dołączyć dane do listy w aplikacjach dla wielu użytkowników. Metoda push() generuje unikalny klucz za każdym razem, gdy nowe dziecko jest dodawane do określonego odwołania Firebase. Korzystając z tych automatycznie generowanych kluczy dla każdego nowego elementu na liście, kilku klientów może jednocześnie dodawać elementy podrzędne do tej samej lokalizacji bez konfliktów zapisu. Unikalny klucz generowany przez push() opiera się na znaczniku czasu, więc elementy listy są automatycznie porządkowane chronologicznie.

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

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

Na przykład push() może służyć do dodawania 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 potomne są wyzwalane w odpowiedzi na określone operacje, które mają miejsce na potomkach węzła z operacji, takiej jak nowy element potomny dodany za pomocą metody push() lub zaktualizowany element potomny za pomocą metody update() .

Wydarzenie Typowe zastosowanie
child_added Pobierz listy elementów lub nasłuchuj dodatków do listy elementów. To zdarzenie jest wywoływane raz dla każdego istniejącego dziecka, a następnie ponownie za każdym razem, gdy nowe dziecko jest dodawane do określonej ścieżki. Odbiornik otrzymuje migawkę zawierającą dane nowego dziecka.
child_changed Posłuchaj zmian w elementach na liście. To zdarzenie jest wywoływane 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 dziecka.
child_removed Nasłuchuj, czy elementy są usuwane z listy. To zdarzenie jest wywoływane po usunięciu bezpośredniego elementu podrzędnego. Migawka przekazana do bloku wywołania zwrotnego zawiera dane usuniętego elementu podrzędnego.
child_moved Nasłuchuj zmian w 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 kolejności).

Każdy z nich razem może być przydatny do nasłuchiwania zmian w określonym węźle w bazie danych. Na przykład aplikacja do blogowania społecznościowego może używać tych metod 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);
});

Posłuchaj wydarzeń o wartości

Chociaż 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 przełączyć, aby uzyskać dostęp do poszczególnych elementów podrzędnych.

Nawet jeśli istnieje tylko jedno dopasowanie dla 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 Realtime Database Query , aby pobrać dane posortowane według klucza, wartości lub wartości elementu podrzędnego. Posortowany wynik można również filtrować według określonej liczby wyników lub zakresu kluczy lub wartości.

Sortuj dane

Aby pobrać posortowane dane, zacznij od określenia jednej z metod uporządkowania według, aby określić sposób uporządkowania 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 podrzędnych.
orderByValue() Uporządkuj wyniki według wartości podrzędnych.

Możesz użyć tylko jednej metody zamówienia na raz. Wielokrotne wywoływanie metody order-by w tym samym zapytaniu powoduje błąd.

Poniższy przykład pokazuje, jak można pobrać listę najlepszych postów użytkownika posortowanych 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 odbiornikiem 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, które otrzymał każdy post. Ta technika używania identyfikatorów jako kluczy indeksowych nazywana jest rozproszeniem danych, możesz przeczytać o niej więcej w rozdziale Struktura bazy danych .

Wywołanie metody orderByChild() określa klucz podrzędny, według którego ma być uporządkowane wyniki. W takim przypadku wpisy są sortowane według wartości ich odpowiedniego elementu podrzędnego "starCount" . Zapytania mogą być również porządkowane według zagnieżdżonych elementów potomnych, 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ć elementy naszej listy według wartości zagnieżdżonych w kluczu metrics , określając względną ścieżkę do zagnieżdżonego elementu potomnego w naszym 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 kolejności innych typów danych, zobacz Jak uporządkowane są dane zapytań .

Filtrowanie danych

Aby filtrować dane, podczas konstruowania zapytania można połączyć dowolną metodę limitu lub zakresu z metodą kolejności 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 od 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 sortowania według.
startAfter() Zwróć przedmioty większe niż określony klucz lub wartość w zależności od wybranej metody sortowania według.
endAt() Zwróć elementy mniejsze lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania według.
endBefore() Zwróć przedmioty mniejsze niż określony klucz lub wartość w zależności od wybranej metody sortowania według.
equalTo() Zwróć pozycje równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania według.

W przeciwieństwie do metod uporządkowania według, można łączyć wiele funkcji limitu lub zakresu. Na przykład można połączyć metody startAt() i endAt() , aby ograniczyć wyniki do określonego zakresu wartości.

Ogranicz liczbę wyników

Możesz użyć limitToFirst() i limitToLast() , aby ustawić maksymalną liczbę dzieci, które mają być synchronizowane 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 zapisanych w bazie danych child_added , dla każdego elementu zostanie wywołane zdarzenie child_added.

Gdy elementy się zmieniają, otrzymujesz zdarzenia child_added dla elementów, które wchodzą w zapytanie i zdarzenia child_removed dla elementów, które z niego wypadają, tak aby łączna liczba pozostała na poziomie 100.

Poniższy przykład ilustruje, 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 listener .

Filtruj według klucza lub wartości

Możesz użyć startAt() , startAfter() , endAt() , endBefore() i equalTo() , aby wybrać dowolny początek, koniec i punkty równoważności dla zapytań. Może to być przydatne do stronicowania danych lub znajdowania elementów z dziećmi, 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 uporządkowania 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 podrzędnego są następne. Jeśli wiele elementów potomnych 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 potomnych ma wartość true , są one sortowane leksykograficznie według klucza.
  4. Następne są dzieci z wartością numeryczną, posortowane w porządku rosnącym. 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 pojawiają się po liczbach i są posortowane 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 znajdują się 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 kolejności rosnącej według klucza.

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

orderByValue

Podczas korzystania z orderByValue() , dzieci są uporządkowane według ich wartości. Kryteria porządkowania są takie same jak w orderByChild() , z tym wyjątkiem, ż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ąć pojedynczy odbiornik, przekazując go jako parametr do off() . Wywołanie off() w lokalizacji bez argumentów usuwa wszystkie detektory w tej lokalizacji.

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

Następne kroki