Pracuj z listami danych na platformach Apple

Uzyskaj FIRDatabaseReference

Aby odczytać lub zapisać dane z bazy danych, potrzebujesz instancji FIRDatabaseReference :

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
var ref: DatabaseReference!

ref = Database.database().reference()

Cel C

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

Czytanie i pisanie list

Dołącz do listy danych

Użyj metody childByAutoId , aby dołączyć dane do listy w aplikacjach dla wielu użytkowników. Metoda childByAutoId generuje unikalny klucz za każdym razem, gdy do określonego odwołania Firebase dodawane jest nowe dziecko. Używając automatycznie generowanych kluczy dla każdego nowego elementu na liście, kilku klientów może dodać elementy podrzędne do tej samej lokalizacji w tym samym czasie, bez konfliktów zapisu. Unikalny klucz wygenerowany przez childByAutoId 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ę childByAutoId , aby uzyskać wartość automatycznie wygenerowanego klucza dziecka lub ustawić dane dla dziecka. Wywołanie metody getKey w odniesieniu do odwołania childByAutoId zwraca 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 rozłożenia danych.

Słuchaj wydarzeń podrzędnych

Zdarzenia podrzędne są wyzwalane w odpowiedzi na określone operacje, które mają miejsce na elementach podrzędnych węzła w wyniku operacji, takiej jak dodanie nowego elementu podrzędnego za pomocą metody childByAutoId lub aktualizacja elementu podrzędnego za pomocą metody updateChildValues .

Typ wydarzenia Typowe użycie
FIRDataEventTypeChildAdded 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 dodawane jest nowe dziecko. Do słuchacza przekazywana jest migawka zawierająca dane nowego dziecka.
FIRDataEventTypeChildChanged Słuchaj zmian w elementach na liście. To zdarzenie jest wyzwalane za każdym razem, gdy modyfikuje się węzeł podrzędny. Obejmuje to wszelkie modyfikacje elementów podrzędnych węzła podrzędnego. Migawka przekazana do detektora zdarzeń zawiera zaktualizowane dane elementu podrzędnego.
FIRDataEventTypeChildRemoved Posłuchaj, czy elementy są usuwane z listy. To zdarzenie jest wywoływane w przypadku usunięcia bezpośredniego dziecka. Migawka przekazana do bloku wywołania zwrotnego zawiera dane usuniętego dziecka.
FIRDataEventTypeChildMoved Słuchaj zmian w kolejności elementów na uporządkowanej liście. To zdarzenie jest wywoływane za każdym razem, gdy aktualizacja powoduje zmianę kolejności elementu podrzędnego. Jest używany z danymi uporządkowanymi przez queryOrderedByChild lub queryOrderedByValue .

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 łącznie do monitorowania aktywności w komentarzach do wpisu, jak pokazano poniżej:

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
// Listen for new comments in the Firebase database
commentsRef.observe(.childAdded, with: { (snapshot) -> Void in
  self.comments.append(snapshot)
  self.tableView.insertRows(
    at: [IndexPath(row: self.comments.count - 1, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})
// Listen for deleted comments in the Firebase database
commentsRef.observe(.childRemoved, with: { (snapshot) -> Void in
  let index = self.indexOfMessage(snapshot)
  self.comments.remove(at: index)
  self.tableView.deleteRows(
    at: [IndexPath(row: index, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})

Cel C

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
// Listen for new comments in the Firebase database
[_commentsRef
              observeEventType:FIRDataEventTypeChildAdded
              withBlock:^(FIRDataSnapshot *snapshot) {
                [self.comments addObject:snapshot];
                [self.tableView insertRowsAtIndexPaths:@[
                  [NSIndexPath indexPathForRow:self.comments.count - 1 inSection:kSectionComments]
                ]
                                      withRowAnimation:UITableViewRowAnimationAutomatic];
              }];
// Listen for deleted comments in the Firebase database
[_commentsRef
 observeEventType:FIRDataEventTypeChildRemoved
 withBlock:^(FIRDataSnapshot *snapshot) {
   int index = [self indexOfMessage:snapshot];
   [self.comments removeObjectAtIndex:index];
   [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:kSectionComments]]
                         withRowAnimation:UITableViewRowAnimationAutomatic];
 }];

Słuchaj wydarzeń wartościowych

Chociaż nasłuchiwanie zdarzeń podrzędnych jest zalecanym sposobem odczytywania list danych, w niektórych sytuacjach przydatne jest nasłuchiwanie zdarzeń wartościowych na liście.

Dołączenie obserwatora FIRDataEventTypeValue do listy danych spowoduje zwrócenie całej listy danych w postaci pojedynczego DataSnapshot, który można następnie zapętlić, aby uzyskać dostęp do poszczególnych elementów podrzędnych.

Nawet jeśli zapytanie odpowiada tylko jednemu dopasowaniu, zrzut ekranu nadal jest listą; zawiera tylko jeden element. Aby uzyskać dostęp do elementu, musisz zapętlić wynik:

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Cel C

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
[_commentsRef
              observeEventType:FIRDataEventTypeValue
              withBlock:^(FIRDataSnapshot *snapshot) {
                // Loop over children
                NSEnumerator *children = [snapshot children];
                FIRDataSnapshot *child;
                while (child = [children nextObject]) {
                  // ...
                }
              }];

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

Sortowanie i filtrowanie danych

Za pomocą klasy FIRDatabaseQuery bazy danych czasu rzeczywistego można pobierać dane posortowane według klucza, wartości lub wartości elementu podrzędnego. Możesz także filtrować posortowane wyniki 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 porządkowania, aby określić sposób uporządkowania wyników:

metoda Stosowanie
queryOrderedByKey Uporządkuj wyniki według kluczy podrzędnych.
queryOrderedByValue Uporządkuj wyniki według wartości podrzędnych.
queryOrderedByChild Uporządkuj wyniki według wartości określonego klucza podrzędnego lub zagnieżdżonej ścieżki podrzędnej.

Możesz użyć tylko jednej metody sortowania na raz. Wielokrotne wywołanie metody sortowania według tego samego zapytania powoduje błąd.

Poniższy przykład ilustruje sposób pobrania listy najpopularniejszych postów użytkownika posortowanych według liczby gwiazdek:

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
// My top posts by number of stars
let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")

Cel C

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
// My top posts by number of stars
FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"]
                                      child:[super getUid]]
                                     queryOrderedByChild:@"starCount"];

To zapytanie pobiera posty 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 indeksujących nazywa się rozdzielaniem danych, możesz przeczytać więcej na ten temat w Strukturuj swoją bazę danych .

Wywołanie metody queryOrderedByChild określa klucz podrzędny, według którego mają zostać uporządkowane wyniki. W tym przykładzie posty są sortowane według wartości elementu podrzędnego "starCount" w każdym poście. Zapytania można także porządkować według zagnieżdżonych elementów podrzędnych, 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 naszej listy według wartości zagnieżdżonych pod kluczem metrics , określając względną ścieżkę do zagnieżdżonego elementu podrzędnego w naszym wywołaniu queryOrderedByChild .

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

Cel C

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

Więcej informacji na temat porządkowania innych typów danych można znaleźć w artykule Jak uporządkowane są dane zapytań .

Filtrowanie danych

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

metoda Stosowanie
queryLimitedToFirst Ustawia maksymalną liczbę elementów do zwrócenia od początku uporządkowanej listy wyników.
queryLimitedToLast Ustawia maksymalną liczbę elementów zwracanych z końca uporządkowanej listy wyników.
queryStartingAtValue Zwróć elementy większe lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
queryStartingAfterValue Zwróć pozycje większe niż określony klucz lub wartość, w zależności od wybranej metody sortowania.
queryEndingAtValue Zwróć produkty mniejsze lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody zamawiania.
queryEndingBeforeValue Zwróć produkty o wartości mniejszej niż określony klucz lub wartość, w zależności od wybranej metody zamawiania.
queryEqualToValue Zwróć pozycje równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.

W przeciwieństwie do metod sortowania, można łączyć wiele funkcji limitów lub zakresów. Można na przykład połączyć metody queryStartingAtValue i queryEndingAtValue , aby ograniczyć wyniki do określonego zakresu wartości.

Ogranicz liczbę wyników

Możesz użyć metod queryLimitedToFirst i queryLimitedToLast , aby ustawić maksymalną liczbę dzieci, które mają być synchronizowane dla danego wywołania zwrotnego. Na przykład, jeśli użyjesz queryLimitedToFirst do ustawienia limitu na 100, początkowo otrzymasz tylko do 100 wywołań zwrotnych FIRDataEventTypeChildAdded . Jeśli w bazie danych Firebase znajduje się mniej niż 100 elementów, dla każdego elementu uruchamiane jest wywołanie zwrotne FIRDataEventTypeChildAdded .

Gdy elementy się zmienią, otrzymasz wywołania zwrotne FIRDataEventTypeChildAdded dla elementów, które wejdą do zapytania, oraz wywołania zwrotne FIRDataEventTypeChildRemoved dla elementów, które z niego wypadną, tak że łączna liczba pozostanie na poziomie 100.

Poniższy przykład ilustruje, jak przykładowa aplikacja do blogowania może pobrać listę 100 najnowszych postów wszystkich użytkowników:

Szybki

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!

Cel C

Uwaga: ten produkt Firebase nie jest dostępny w docelowym klipie aplikacji.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

Filtruj według klucza lub wartości

Za pomocą queryStartingAtValue , queryStartingAfterValue , queryEndingAtValue , queryEndingBeforeValue i queryEqualToValue można wybrać dowolne punkty początkowe, końcowe i równoważne 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ść.

Sposób uporządkowania danych zapytania

W tej sekcji wyjaśniono, w jaki sposób dane są sortowane według każdej metody porządkowania w klasie FIRDatabaseQuery .

queryOrderedByKey

Jeśli do sortowania danych używasz queryOrderedByKey , dane są zwracane w kolejności rosnącej według klucza.

  1. Na pierwszym miejscu znajdują się dzieci z kluczem, który można przeanalizować jako 32-bitową liczbę całkowitą, posortowane w kolejności rosnącej.
  2. Następne są dzieci, których kluczem jest wartość ciągu, posortowane leksykograficznie w kolejności rosnącej.

queryOrderedByValue

Podczas korzystania z queryOrderedByValue elementy podrzędne są sortowane według ich wartości. Kryteria porządkowania są takie same jak w queryOrderedByChild , z tą różnicą, że zamiast wartości określonego klucza podrzędnego używana jest wartość węzła.

queryOrderedByChild

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

  1. Dzieci z wartością nil dla określonego klucza podrzędnego są traktowane jako pierwsze.
  2. Następne są dzieci z wartością false dla określonego klucza podrzędnego. Jeśli wiele elementów podrzędnych ma wartość false , są one sortowane leksykograficznie według klucza.
  3. Następne są dzieci z wartością true dla określonego klucza podrzędnego. 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 w kolejności rosnącej. 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 znaków występują po liczbach i są sortowane leksykograficznie w kolejności rosnącej. 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ą umieszczane na końcu i są sortowane leksykograficznie według kluczy w kolejności rosnącej.

Odłącz słuchaczy

Obserwatorzy nie przestają automatycznie synchronizować danych, gdy opuścisz ViewController . Jeśli obserwator nie zostanie prawidłowo usunięty, będzie kontynuował synchronizację danych z pamięcią lokalną i zachowa wszelkie obiekty przechwycone podczas zamknięcia procedury obsługi zdarzeń, co może spowodować wycieki pamięci. Gdy obserwator nie jest już potrzebny, usuń go, przekazując powiązany FIRDatabaseHandle do metody removeObserverWithHandle .

Po dodaniu bloku wywołania zwrotnego do odwołania zwracany jest FIRDatabaseHandle . Uchwyty te można wykorzystać do usunięcia bloku wywołania zwrotnego.

Jeśli do odwołania do bazy danych dodano wiele detektorów, każdy detektor jest wywoływany po wywołaniu zdarzenia. Aby zatrzymać synchronizację danych w tej lokalizacji, należy usunąć wszystkich obserwatorów w tej lokalizacji, wywołując metodę removeAllObservers .

Wywołanie metody removeObserverWithHandle lub removeAllObservers na odbiorniku nie powoduje automatycznego usunięcia odbiorników zarejestrowanych w jego węzłach podrzędnych; musisz także śledzić te odniesienia lub uchwyty, aby je usunąć.

Następne kroki