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

Odczytywanie i zapisywanie list

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 odniesienia Firebase dodawany jest nowy element podrzędny. Dzięki użyciu 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ć odniesienia do nowych danych zwróconego przez metodę push(), aby uzyskać wartość automatycznie wygenerowanego klucza elementu podrzędnego lub ustawić dane dla elementu podrzędnego. Właściwość .key odniesienia push() zawiera automatycznie wygenerowany klucz.

Możesz użyć tych automatycznie wygenerowanych kluczy, aby uprościć spłaszczanie struktury danych. Więcej informacji znajdziesz w przykładzie zwielokrotnienia wyjściowego 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ń podrzędnych

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

Zdarzenie Typowe użycie
child_added Pobieranie list elementów lub nasłuchiwanie dodatków do listy elementów. To zdarzenie jest wywoływane raz dla każdego istniejącego elementu podrzędnego, a następnie za każdym razem gdy do określonej ścieżki dodawany jest nowy element podrzędny. Do odbiornika przekazywany jest snapshot zawierający dane nowego elementu podrzędnego.
child_changed Nasłuchiwanie zmian w elementach listy. To zdarzenie jest wywoływane za każdym razem, gdy modyfikowany jest węzeł podrzędny. Obejmuje to wszelkie modyfikacje elementów potomnych węzła podrzędnego. Migawka przekazywana do detektora zdarzeń zawiera zaktualizowane dane elementu podrzędnego.
child_removed Nasłuchiwanie elementów usuwanych z listy. To zdarzenie jest wywoływane, gdy usuwany jest bezpośredni element podrzędny.Snapshot przekazywany do bloku wywołania zwrotnego zawiera dane usuniętego elementu podrzędnego.
child_moved Nasłuchiwanie 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 biebieżącej metody sortowania).

Wszystkie te zdarzenia mogą 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 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 jest zalecanym sposobem 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 snapshotu, który można następnie iterować, aby uzyskać dostęp do poszczególnych elementów podrzędnych.

Nawet jeśli zapytanie znajdzie tylko 1 pasujący element, snapshot nadal będzie listą, ale będzie zawierać tylko 1 element. Aby uzyskać dostęp do elementu, musisz iterować wynik:

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

Aby pobrać dane posortowane według klucza, wartości lub wartości elementu podrzędnego, możesz użyć klasy Realtime Database Query. Możesz też filtrować posortowany wynik do określonej liczby wyników lub zakresu kluczy lub wartości.

Sortowanie danych

Aby pobrać posortowane dane, zacznij od określenia jednej z metod sortowania, która określi kolejność wyników:

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

Możesz używać tylko jednej metody sortowania naraz. Wywołanie metody sortowania kilka razy w tym samym zapytaniu spowoduje błąd.

Poniższy przykład pokazuje, jak można 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 to zapytanie, które w połączeniu z odbiornikiem elementu podrzędnego synchronizuje klienta z postami użytkownika ze ścieżki w bazie danych na podstawie jego identyfikatora użytkownika, posortowanymi według liczby gwiazdek otrzymanych przez każdy post. Ta technika używania identyfikatorów jako kluczy indeksu nazywa się zwielokrotnieniem wyjściowym danych. Więcej informacji znajdziesz w artykule Struktura bazy danych.

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

"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 tym przypadku możemy sortować elementy listy według wartości zagnieżdżonych pod kluczem metrics, określając ścieżkę względną 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 tym, jak sortowane są inne typy danych, zobacz Jak sortowane są dane zapytań.

Filtrowanie danych

Aby filtrować dane, możesz połączyć dowolną z metod limitu lub zakresu z metodą sortowania podczas tworzenia zapytania.

Metoda Wykorzystanie
limitToFirst() Ustawia maksymalną liczbę elementów do zwrócenia z początku posortowanej listy wyników.
limitToLast() Ustawia maksymalną liczbę elementów do zwrócenia z końca posortowanej listy wyników.
startAt() Zwraca elementy większe lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
startAfter() Zwraca elementy większe od określonego klucza lub wartości w zależności od wybranej metody sortowania.
endAt() Zwraca elementy mniejsze lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
endBefore() Zwraca elementy mniejsze od określonego klucza lub wartości 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ć ze sobą kilka funkcji limitu lub zakresu. Możesz na przykład połączyć metody startAt() i endAt(), aby ograniczyć wyniki do określonego zakresu wartości.

Ograniczanie liczby wyników

Za pomocą metod limitToFirst() i 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 limitToFirst() do ustawienia limitu 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.

Gdy elementy się zmieniają, otrzymujesz zdarzenia child_added dla elementów, które wchodzą w zakres zapytania, oraz zdarzenia child_removed dla elementów, które z niego wypadają, tak aby łączna liczba elementów wynosiła 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, trzeba dołączyć do niego odbiornik.

Filtrowanie według klucza lub wartości

Za pomocą metod startAt(), startAfter(), endAt(), endBefore() i equalTo() możesz wybrać dowolne punkty początkowe, końcowe i równoważności dla zapytań. Może to być przydatne do paginacji danych lub znajdowania elementów z elementami podrzędnymi o określonej wartości.

Jak sortowane są dane zapytań

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

orderByChild

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

  1. Najpierw elementy podrzędne z wartością null dla określonego klucza elementu podrzędnego.
  2. Następnie elementy podrzędne z wartością false dla określonego klucza elementu podrzędnego. Jeśli kilka elementów podrzędnych ma wartość false, są one sortowane leksykograficznie według klucza.
  3. Następnie elementy podrzędne z wartością true dla określonego klucza elementu podrzędnego przychodzą następne. Jeśli kilka elementów podrzędnych ma wartość true, są one sortowane leksykograficznie według klucza.
  4. Następnie 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ą dla określonego węzła podrzędnego, są one sortowane według klucza.
  5. Po liczbach występują ciągi znaków, które są sortowane leksykograficznie w kolejności rosnącej. Jeśli kilka elementów podrzędnych ma tę samą wartość dla określonego węzła podrzędnego, są one sortowane leksykograficznie według klucza.
  6. Na końcu występują obiekty, które są sortowane leksykograficznie według klucza w kolejności rosnącej.

orderByKey

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

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

orderByValue

Gdy używasz orderByValue(), elementy podrzędne są sortowane według ich wartości. Kryteria sortowania są takie same jak w przypadku orderByChild(), z tym że zamiast wartości określonego klucza elementu podrzędnego używana jest wartość węzła.

Odłączanie odbiorników

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

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

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

Dalsze kroki