Praca z listami danych w internecie

Pobieranie odniesienia do bazy danych

Aby odczytywać lub zapisywać dane w bazie danych, potrzebujesz instancji firebase.database.Reference:

Web

import { getDatabase } from "firebase/database";

const database = getDatabase();

Web

var database = firebase.database();

Listy czytelnicze i listy do pisania

Dołączanie do listy danych

Użyj metody push(), aby dołączyć dane do listy w aplikacjach wielodostępnych. Metoda push() generuje unikalny klucz za każdym razem, gdy do określonego odwołania Firebase dodawane jest nowe dziecko. Dzięki używaniu 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() jest oparty na sygnaturze czasowej, 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 elementu podrzędnego lub ustawić dane elementu podrzędnego. Właściwość .key odwołania push() zawiera klucz wygenerowany automatycznie.

Możesz używać tych automatycznie generowanych kluczy, aby uprościć spłaszczanie struktury danych. Więcej informacji znajdziesz w przykładzie dotyczącym rozsyłania danych.

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

Web

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

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

Nasłuchiwanie zdarzeń dotyczących dziecka

Zdarzenia podrzędne są wywoływane w odpowiedzi na określone operacje wykonywane na elementach podrzędnych węzła, np. dodanie nowego elementu podrzędnego za pomocą metody push() lub zaktualizowanie elementu podrzędnego za pomocą metody update().

Zdarzenie Typowe zastosowanie
child_added pobierać listy elementów lub nasłuchiwać dodawania elementów do listy; To zdarzenie jest wywoływane raz dla każdego istniejącego elementu podrzędnego, a potem ponownie za każdym razem, gdy do określonej ścieżki zostanie dodany nowy element podrzędny. Do odbiorcy przekazywany jest zrzut zawierający nowe dane dziecka.
child_changed Monitorowanie zmian w elementach na liście. To zdarzenie jest wywoływane za każdym razem, gdy węzeł podrzędny zostanie zmodyfikowany. Obejmuje to wszelkie modyfikacje elementów podrzędnych węzła podrzędnego. Zrzut przekazany do odbiornika zdarzeń zawiera zaktualizowane dane dotyczące elementu podrzędnego.
child_removed Nasłuchiwanie elementów usuwanych z listy. To zdarzenie jest wywoływane, gdy zostanie usunięty bezpośredni element podrzędny.Zrzut przekazywany do bloku wywołania zwrotnego zawiera dane usuniętego elementu podrzędnego.
child_moved Nasłuchiwanie zmian kolejności elementów na liście numerowanej. Zdarzenia child_moved zawsze następują po zdarzeniu child_changed, które spowodowało zmianę kolejności elementów (zgodnie z obecną metodą sortowania).

Każda z tych funkcji może być przydatna do śledzenia 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

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

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

Nasłuchiwanie zdarzeń wartości

Nasłuchiwanie zdarzeń podrzędnych to zalecany sposób odczytywania list danych, ale w niektórych sytuacjach przydatne jest nasłuchiwanie zdarzeń wartości w odniesieniu do listy.

Dołączenie obserwatora value do listy danych spowoduje zwrócenie całej listy danych jako pojedynczego zrzutu, po którym możesz iterować, aby uzyskać dostęp do poszczególnych elementów podrzędnych.

Nawet jeśli zapytanie zwraca tylko 1 wynik, migawka jest listą, która zawiera tylko 1 element. Aby uzyskać dostęp do elementu, musisz wykonać pętlę po wyniku:

Web

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

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 ramach jednej operacji, zamiast nasłuchiwać dodatkowych zdarzeń dodania elementu podrzędnego.

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. Możesz też filtrować posortowane wyniki, aby uzyskać określoną liczbę wyników lub zakres kluczy lub wartości.

Sortowanie danych

Aby pobrać posortowane dane, zacznij od określenia jednej z metod sortowania, aby określić sposób sortowania wyników:

Metoda Wykorzystanie
orderByChild() Sortowanie wyników według wartości określonego klucza podrzędnego lub zagnieżdżonej ścieżki podrzędnej.
orderByKey() Sortuj wyniki według kluczy podrzędnych.
orderByValue() Sortuj wyniki według wartości elementów podrzędnych.

Możesz używać tylko jednej metody zamawiania naraz. Wywołanie metody order-by kilka razy w tym samym zapytaniu powoduje błąd.

Poniższy przykład pokazuje, jak pobrać listę najpopularniejszych postów użytkownika posortowanych według liczby gwiazdek:

Web

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

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

Definiuje zapytanie, które w połączeniu z elementem nasłuchującym podrzędnym synchronizuje klienta z postami użytkownika z ścieżki w bazie danych na podstawie jego identyfikatora, uporządkowanymi według liczby gwiazdek, które otrzymał każdy post. Technika używania identyfikatorów jako kluczy indeksu nazywa się rozgałęzianiem danych. Więcej informacji znajdziesz w artykule Struktura bazy danych.

Wywołanie metody orderByChild() określa klucz podrzędny, według którego mają być uporządkowane wyniki. W tym przypadku posty są sortowane według wartości odpowiedniego elementu podrzędnego "starCount". Zapytania można też porządkować według zagnieżdżonych elementów podrzędnych, jeśli masz dane w takim formacie:

"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 listy według wartości zagnieżdżonych pod kluczem metrics, podając względną ścieżkę do zagnieżdżonego elementu podrzędnego w wywołaniu orderByChild().

Web

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

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

Web

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

Więcej informacji o kolejności innych typów danych znajdziesz w artykule Jak są uporządkowane dane zapytań.

Filtrowanie danych

Aby filtrować dane, możesz łączyć dowolne metody ograniczania lub zakresu z metodą sortowania podczas tworzenia zapytania.

Metoda Wykorzystanie
limitToFirst() Określa maksymalną liczbę elementów do zwrócenia z 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() Zwraca elementy o wartości klucza lub wartości większej lub równej podanej wartości, w zależności od wybranej metody sortowania.
startAfter() Zwraca elementy o wartości większej niż określony klucz lub wartość w zależności od wybranej metody sortowania.
endAt() Zwraca produkty o wartości klucza lub wartości mniejszej lub równej określonej wartości, w zależności od wybranej metody sortowania.
endBefore() Zwraca produkty o wartości mniejszej niż określony klucz lub wartość w zależności od wybranej metody sortowania.
equalTo() Zwraca elementy równe określonemu kluczowi lub wartości w zależności od wybranej metody sortowania.

W przeciwieństwie do metod sortowania możesz łączyć wiele funkcji limitu lub zakresu. Możesz np. połączyć metody startAt()endAt(), aby ograniczyć wyniki do określonego zakresu wartości.

Ograniczanie liczby wyników

Za pomocą metod limitToFirst()limitToLast() możesz ustawić maksymalną liczbę elementów podrzędnych, które mają być synchronizowane w przypadku danego zdarzenia. Jeśli na przykład użyjesz funkcji limitToFirst(), aby ustawić limit 100, początkowo otrzymasz tylko do 100 zdarzeń child_added. Jeśli w bazie danych Firebase masz mniej niż 100 elementów, dla każdego z nich zostanie wywołane zdarzenie child_added.

W miarę zmian w produktach otrzymujesz zdarzenia child_added dotyczące produktów, które pojawiają się w zapytaniu, oraz zdarzenia child_removed dotyczące produktów, które z niego znikają, dzięki czemu łączna liczba produktów pozostaje na poziomie 100.

Poniższy przykład pokazuje, jak przykładowa aplikacja do blogowania definiuje zapytanie, aby pobrać listę 100 najnowszych postów wszystkich użytkowników:

Web

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

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

Web

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

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

Filtrowanie według klucza lub wartości

Możesz użyć zasad startAt(), startAfter(), endAt(), endBefore()equalTo(), aby wybrać dowolne punkty początkowe, końcowe i równoważności dla zapytań. Może to być przydatne w przypadku stronicowania danych lub wyszukiwania elementów podrzędnych o określonej wartości.

Sposób uporządkowania danych zapytania

W tej sekcji wyjaśniamy, jak dane są sortowane za pomocą każdej z metod sortowania w klasie Query.

orderByChild

Gdy używasz orderByChild(), dane zawierające określony klucz podrzędny są porządkowane w ten sposób:

  1. Najpierw pojawiają się dzieci z wartością null dla określonego klucza dziecka.
  2. Następnie wyświetlane są dzieci z wartością false dla określonego klucza podrzędnego. Jeśli kilka elementów podrzędnych ma wartość false, są one sortowane leksykograficznie według klucza.
  3. Następnie wyświetlane są dzieci z wartością true dla określonego klucza podrzędnego. Jeśli kilka elementów podrzędnych ma wartość true, są one sortowane leksykograficznie według klucza.
  4. Następnie pojawiają się elementy podrzędne z wartością liczbową, posortowane w kolejności rosnącej. Jeśli kilka elementów podrzędnych ma tę samą wartość liczbową w przypadku określonego węzła podrzędnego, są one sortowane według klucza.
  5. Ciągi znaków występują po liczbach i są sortowane leksykograficznie w kolejności rosnącej. Jeśli kilka węzłów podrzędnych ma tę samą wartość, są one uporządkowane leksykograficznie według klucza.
  6. Obiekty są umieszczane na końcu i sortowane leksykograficznie według klucza w kolejności rosnącej.

orderByKey

Gdy używasz funkcji orderByKey() do sortowania danych, są one zwracane w kolejności rosnącej według klucza.

  1. Najpierw pojawiają się dzieci z kluczem, który można przeanalizować jako 32-bitową liczbę całkowitą, posortowane w kolejności rosnącej.
  2. Następnie pojawiają się dzieci z wartością tekstową jako kluczem, posortowane leksykograficznie w kolejności rosnącej.

orderByValue

W przypadku korzystania z orderByValue() dzieci są uporządkowane według wartości. Kryteria sortowania są takie same jak w przypadku orderByChild(), z tym że zamiast wartości określonego klucza podrzędnego używana jest wartość węzła.

Odłączanie detektorów

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

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

Wywołanie off() na odbiorniku rodzica nie powoduje automatycznego usunięcia odbiorników zarejestrowanych w jego węzłach podrzędnych. Aby usunąć wywołanie zwrotne, należy też wywołać off() na wszystkich odbiornikach podrzędnych.

Dalsze kroki