Korzystanie z list danych na platformach Apple

Pobieranie FIRDatabaseReference

Aby odczytywać lub zapisywać dane w bazie danych, potrzebujesz instancji FIRDatabaseReference:

Swift

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
@property (strong, nonatomic) FIRDatabaseReference *ref;

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

Odczytywanie i zapisywanie list

Dołączanie do listy danych

Aby dołączyć dane do listy w aplikacjach wielodostępnych, użyj metody childByAutoId. Metoda childByAutoId generuje unikalny klucz za każdym razem, gdy do określonego odwołania Firebase dodawany jest nowy element podrzędny. 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 w tej samej lokalizacji bez konfliktów zapisu. Unikalny klucz generowany przez childByAutoId jest oparty na sygnaturze czasowej, więc elementy listy są automatycznie porządkowane chronologicznie.

Możesz użyć odwołania do nowych danych zwracanego przez metodę childByAutoId, aby uzyskać wartość automatycznie wygenerowanego klucza elementu podrzędnego lub ustawić dane dla elementu podrzędnego. Wywołanie getKey w odwołaniu childByAutoId zwraca automatycznie wygenerowany klucz.

Możesz użyć tych automatycznie generowanych kluczy, aby uprościć spłaszczanie struktury danych. Więcej informacji znajdziesz w przykładzie zwielokrotnienia wyjściowego danych .

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 childByAutoId lub zaktualizowanie elementu podrzędnego za pomocą metody updateChildValues.

Typ zdarzenia Typowe zastosowanie
FIRDataEventTypeChildAdded 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. Detektor otrzymuje migawkę zawierającą dane nowego elementu podrzędnego.
FIRDataEventTypeChildChanged 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.
FIRDataEventTypeChildRemoved Nasłuchiwanie elementów usuwanych z listy. To zdarzenie jest wywoływane, gdy usuwany jest bezpośredni element podrzędny.Migawka przekazywana do bloku wywołania zwrotnego zawiera dane usuniętego elementu podrzędnego.
FIRDataEventTypeChildMoved Nasłuchiwanie zmian 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żywane z danymi uporządkowanymi według queryOrderedByChild lub queryOrderedByValue.

Każde z tych zdarzeń może 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:

Swift

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
// 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
  )
})

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
// 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];
 }];

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 detektora FIRDataEventTypeValue do listy danych spowoduje zwrócenie całej listy danych jako pojedynczej migawki danych, którą 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, migawka nadal będzie listą, tylko z 1 elementem. Aby uzyskać dostęp do elementu, musisz iterować wynik:

Swift

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
[_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 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 FIRDatabaseQuery. 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 sposób porządkowania wyników:

Metoda Wykorzystanie
queryOrderedByKey Porządkowanie wyników według kluczy elementów podrzędnych.
queryOrderedByValue Porządkowanie wyników według wartości elementów podrzędnych.
queryOrderedByChild Porządkowanie wyników według wartości określonego klucza elementu podrzędnego lub zagnieżdżonej ścieżki elementu podrzędnego.

W danym momencie możesz używać tylko 1 metody sortowania. Wywołanie metody sortowania kilka razy w tym samym zapytaniu powoduje błąd.

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

Swift

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
// My top posts by number of stars
let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
// 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, uporządkowane według liczby gwiazdek otrzymanych przez każdy post. Ta technika używania identyfikatorów jako kluczy indeksu nazywa się rozsyłaniem danych. Więcej informacji znajdziesz w artykule Struktura bazy danych.

Wywołanie metody queryOrderedByChild określa klucz elementu podrzędnego, według którego mają być porzą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 też porządkować 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 takim przypadku możemy porzą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 queryOrderedByChild.

Swift

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

Więcej informacji o tym, jak porządkowane są inne typy danych, zobacz Jak porządkowane są dane zapytań.

Filtrowanie danych

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

Metoda Wykorzystanie
queryLimitedToFirst Ustawia maksymalną liczbę elementów do zwrócenia z początku uporządkowanej listy wyników.
queryLimitedToLast Ustawia maksymalną liczbę elementów do zwrócenia z końca uporządkowanej listy wyników.
queryStartingAtValue Zwraca elementy większe lub równe określonej wartości klucza, w zależności od wybranej metody sortowania.
queryStartingAfterValue Zwraca elementy większe od określonej wartości klucza, w zależności od wybranej metody sortowania.
queryEndingAtValue Zwraca elementy mniejsze lub równe określonej wartości klucza, w zależności od wybranej metody sortowania.
queryEndingBeforeValue Zwraca elementy mniejsze od określonej wartości klucza, w zależności od wybranej metody sortowania.
queryEqualToValue Zwraca elementy równe określonej wartości klucza, 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 queryStartingAtValue i queryEndingAtValue, aby ograniczyć wyniki do określonego zakresu wartości.

Ograniczanie liczby wyników

Za pomocą metod queryLimitedToFirst i queryLimitedToLast możesz ustawić maksymalną liczbę elementów podrzędnych, które mają być synchronizowane w przypadku danego wywołania zwrotnego. Jeśli na przykład użyjesz queryLimitedToFirst, aby ustawić limit 100, początkowo otrzymasz tylko do 100 wywołań zwrotnych FIRDataEventTypeChildAdded. Jeśli w bazie danych Firebase masz mniej niż 100 elementów, dla każdego z nich zostanie wywołane wywołanie zwrotne FIRDataEventTypeChildAdded.

Gdy elementy się zmieniają, otrzymujesz wywołania zwrotne FIRDataEventTypeChildAdded dla elementów, które wchodzą w zakres zapytania, oraz wywołania zwrotne FIRDataEventTypeChildRemoved dla elementów, które z niego wypadają, tak aby łączna liczba elementów pozostała na poziomie 100.

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

Swift

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w przypadku elementu docelowego App Clip.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

Filtrowanie według klucza lub wartości

Za pomocą metod queryStartingAtValue, queryStartingAfterValue, queryEndingAtValue, queryEndingBeforeValue i queryEqualToValue możesz wybrać dowolne punkty początkowe, końcowe i równoważności dla zapytań. Może to być przydatne do paginowania danych lub znajdowania elementów z elementami podrzędnymi o określonej wartości.

Jak porządkowane są dane zapytań

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

queryOrderedByKey

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

  1. Najpierw pojawiają się 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 pojawiają się elementy podrzędne z wartością ciągu znaków jako kluczem, posortowane leksykograficznie w kolejności rosnącej.

queryOrderedByValue

Gdy używasz queryOrderedByValue, elementy podrzędne są porządkowane według ich wartości. Kryteria porządkowania są takie same jak w przypadku queryOrderedByChild, z tym że zamiast wartości określonego klucza elementu podrzędnego używana jest wartość węzła.

queryOrderedByChild

Gdy używasz queryOrderedByChild, dane zawierające określony klucz elementu podrzędnego są porządkowane w ten sposób:

  1. Najpierw pojawiają się elementy podrzędne z wartością nil dla określonego klucza elementu podrzędnego.
  2. Następnie pojawiają się elementy podrzędne z wartością false dla określonego klucza elementu podrzędnego przyjdź dalej. Jeśli kilka elementów podrzędnych ma wartość false, są one sortowane leksykograficznie według klucza.
  3. Następnie pojawiają się elementy podrzędne z wartością true dla określonego klucza elementu 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ą dla określonego węzła podrzędnego, są one sortowane według klucza.
  5. Po liczbach pojawiają się ciągi znaków, posortowane 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 porządkowane leksykograficznie według klucza.
  6. Obiekty pojawiają się na końcu i są sortowane leksykograficznie według klucza w kolejności rosnącej.

Odłączanie detektorów

Gdy opuszczasz ViewController, detektory nie przestają automatycznie synchronizować danych. Jeśli detektor nie zostanie prawidłowo usunięty, będzie nadal synchronizować dane z pamięcią lokalną i zachowa wszystkie obiekty przechwycone w zamknięciu obsługi zdarzeń, co może spowodować wycieki pamięci. Gdy detektor nie jest już potrzebny, usuń go, przekazując powiązany FIRDatabaseHandle do metody removeObserverWithHandle.

Gdy dodasz blok wywołania zwrotnego do odwołania, zostanie zwrócony FIRDatabaseHandle. Te uchwyty można użyć do usunięcia bloku wywołania zwrotnego.

Jeśli do odwołania do bazy danych dodano kilka detektorów, każdy z nich jest wywoływany, gdy wystąpi zdarzenie. Aby zatrzymać synchronizację danych w tej lokalizacji, musisz usunąć wszystkie detektory w danej lokalizacji, wywołując metodę removeAllObservers.

Wywołanie removeObserverWithHandle lub removeAllObservers w detektorze nie powoduje automatycznego usunięcia detektorów zarejestrowanych w jego węzłach podrzędnych. Aby je usunąć, musisz też śledzić te odwołania lub uchwyty.

Następne kroki