Praca z listami danych w internecie

Pobieranie odniesienia do bazy danych

Aby odczytywać lub zapisywać dane w bazie danych, musisz mieć instancję firebase.database.Reference:

Web

import { getDatabase } from "firebase/database";

const database = getDatabase();

Web

var database = firebase.database();

Czytanie i pisanie list

Dołączanie do listy danych

Aby dołączać dane do listy w aplikacji wielostanowiskowej, użyj metody push(). Metoda push() generuje unikalny klucz za każdym razem, gdy do określonego odwołania Firebase dodawane jest nowe podrzędne. Dzięki tym automatycznie generowanym kluczom dla każdego nowego elementu na liście kilku klientów może jednocześnie dodawać podelementy do tego samego miejsca bez konfliktów podczas zapisu. Unikalny klucz wygenerowany przez funkcję push() opiera się na sygnaturze czasowej, dzięki czemu elementy listy są automatycznie sortowane chronologicznie.

Możesz użyć odwołania do nowych danych zwróconych przez metodę push(), aby uzyskać wartość automatycznie wygenerowanego klucza podrzędnego lub ustawić dane dla tego 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łaszczenie struktury danych. Więcej informacji znajdziesz w przykładzie rozgałęzienia danych.

Na przykład push() można użyć do dodania nowego wpisu do listy wpisó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 podrzędnych węzłach, takie jak dodanie nowego podrzędnego węzła za pomocą metody push() lub zaktualizowanie podrzędnego węzła za pomocą metody update().

Zdarzenie Typowe zastosowanie
child_added pobierać listy elementów lub słuchać dodanych elementów na liście; To zdarzenie jest wywoływane raz dla każdego istniejącego elementu podrzędnego, a potem za każdym razem, gdy do określonej ścieżki zostanie dodany nowy element podrzędny. Słuchacz otrzymuje zrzut zawierający nowe dane dziecka.
child_changed Słuchaj zmian elementów na liście. To zdarzenie jest wywoływane za każdym razem, gdy węzeł podrzędny zostanie zmodyfikowany. Obejmuje to: wszelkie modyfikacje potomków węzła podrzędnego. Zrzut przesłany do odbiornika zdarzeń zawiera zaktualizowane dane dotyczące podrzędnego elementu.
child_removed Słuchaj, czy elementy są usuwane z listy. To zdarzenie jest wywoływane, gdy usuwany jest element podrzędny.Zrzut przekazywany do bloku wywołania zwrotnego zawiera dane elementu podrzędnego, który został usunięty.
child_moved Słuchaj zmian kolejności elementów na liście uporządkowanej. Zdarzenia child_moved zawsze podążają za zdarzeniem child_changed, które spowodowało zmianę kolejności elementów (na podstawie bieżącej metody sortowania).

Każda z nich może być przydatna do monitorowania zmian w określonym węźle w bazie danych. Na przykład aplikacja do blogowania na potrzeby mediów społecznościowych może używać tych metod razem, aby monitorować aktywność w komentarzach do postu, 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

Chociaż wykrywanie zdarzeń podrzędnych jest zalecanym sposobem odczytu list danych, w niektórych sytuacjach przydatne jest wykrywanie zdarzeń wartości na liście referencyjnej.

Dołączenie obserwatora value do listy danych spowoduje zwrócenie całej listy danych jako pojedynczego zrzutu, który możesz następnie przewijać, aby uzyskać dostęp do poszczególnych dzieci.

Nawet wtedy, gdy zapytanie ma tylko 1 pasujące do niego wyniki, snapshot jest nadal listą, ale zawiera tylko 1 element. Aby uzyskać dostęp do elementu, musisz wykonać pętlę na 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

Aby pobrać dane posortowane według klucza, wartości lub wartości podrzędnego, możesz użyć klasy Realtime Database Query. Możesz też ograniczyć liczbę wyników do określonej liczby lub do określonego zakresu kluczy bądź wartości.

Sortowanie danych

Aby pobrać posortowane dane, najpierw określ jedną z metod sortowania, która określi sposób sortowania wyników:

Metoda Wykorzystanie
orderByChild() Uporządkuj wyniki według wartości określonego klucza podrzędnego lub ścieżki podrzędnej ujętej w nawiasach.
orderByKey() Uporządkuj wyniki według kluczy podrzędnych.
orderByValue() Porządkuj wyniki według wartości elementów podrzędnych.

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

Ten 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');

Określa ono zapytanie, które po połączeniu z podrzędnym odbiorcą synchronizuje klienta z postami użytkownika z ścieżki w bazie danych na podstawie jego identyfikatora użytkownika, posortowanymi według liczby gwiazdek przypisanych do każdego posta. Ta technika używania identyfikatorów jako kluczy indeksu nazywa się rozgałęźnikiem 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ć posortowane wyniki. W tym przypadku posty są sortowane według wartości odpowiedniego elementu "starCount" podrzędnego. Zapytania można też sortować według zagnieżdżonych elementów potomnych, jeśli masz dane wyglądające 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 tym przypadku możemy uporządkować 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 porządkowaniu innych typów danych znajdziesz w artykule Porządkowanie danych zapytań.

Filtrowanie danych

Aby filtrować dane, podczas tworzenia zapytania możesz połączyć dowolną metodę limit lub range z metodą order-by.

Metoda Wykorzystanie
limitToFirst() Określa maksymalną liczbę elementów do zwrócenia z początku uporządkowanej listy wyników.
limitToLast() Określa maksymalną liczbę elementów do zwrócenia z końca posortowanej listy wyników.
startAt() Zwraca elementy, których wartość jest większa lub równa określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
startAfter() Zwraca elementy większe niż określony klucz lub wartość, w zależności od wybranej metody sortowania.
endAt() Zwraca elementy o wartości mniejszej lub równej określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
endBefore() Zwraca elementy, które są mniejsze niż określony klucz lub wartość, w zależności od wybranej metody sortowania.
equalTo() Zwraca elementy o wartości określonej w kluczu lub wartości, w zależności od wybranej metody sortowania.

W przeciwieństwie do metod porządkowania według kolumny możesz łączyć wiele funkcji limit i zakres. 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 danym zdarzeniu. 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.

Gdy elementy się zmieniają, otrzymujesz zdarzenia child_added dotyczące elementów, które wchodzą do zapytania, oraz zdarzenia child_removed dotyczące elementów, które z niego wypadają, dzięki czemu łączna liczba pozostaje na poziomie 100.

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

W tym przykładzie zdefiniowano tylko zapytanie. Aby dane mogły być synchronizowane, musi być dołączony odbiorca.

Filtrowanie według klucza lub wartości

Aby wybrać dowolne punkty początkowe, końcowe i równoważne zapytań, możesz użyć znaczników startAt(), startAfter(), endAt(), endBefore()equalTo(). Może to być przydatne do podziału danych na strony lub znajdowania elementów z elementami podrzędnymi o określonej wartości.

Sposób sortowania danych zapytania

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

orderByChild

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

  1. Najpierw są wyświetlane elementy podrzędne, dla których wartość atrybutu podrzędnego null jest równa null.
  2. Następnie podawane są elementy podrzędne, dla których wartość określonego klucza podrzędnego to false. Jeśli wiele elementów podrzędnych ma wartość false, są one sortowane alfabetycznie według klucza.
  3. Następnie podawane są elementy podrzędne, dla których wartość określonego klucza podrzędnego to true. Jeśli wiele elementów podrzędnych ma wartość true, są one sortowane alfabetycznie według klucza.
  4. Następnie pojawiają się elementy z wartością liczbową, posortowane w kolejności rosnącej. Jeśli wiele elementów podrzędnych ma tę samą wartość numeryczną w przypadku określonego węzła podrzędnego, są one sortowane według klucza.
  5. Ciągi tekstowe występują po liczbach i są sortowane alfabetycznie w kolejności rosnącej. Jeśli wiele elementów podrzędnych ma tę samą wartość w wybranym węźle podrzędnym, są one uporządkowane alfabetycznie według klucza.
  6. Obiekty znajdują się na końcu i są posortowane leksykograficznie według klucza w kolejności rosnącej.

orderByKey

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

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

orderByValue

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

Odłączanie słuchaczy

Callbacki 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 funkcji off(). Wywołanie funkcji off() w przypadku lokalizacji bez argumentów powoduje usunięcie wszystkich słuchaczy w tej lokalizacji.

Wywołanie metody off() na odbiorcy nadrzędnym nie powoduje automatycznego usuwania odbiorców zarejestrowanych na jego węzłach podrzędnych. Aby usunąć wywołania zwrotne, należy też wywołać metodę off() na wszystkich odbiorcach podrzędnych.

Dalsze kroki