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 celu App Clip.
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w przypadku celu 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 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ć dzieci do tej samej lokalizacji bez konfliktów zapisu. Unikalny klucz generowany przez childByAutoId jest oparty na sygnaturze czasowej, więc elementy listy są automatycznie uporządkowane chronologicznie.

Możesz użyć odwołania do nowych danych zwróconego przez metodę childByAutoId, aby uzyskać wartość automatycznie wygenerowanego klucza dziecka lub ustawić dane dla dziecka. Wywołanie getKey w odwołaniu childByAutoId zwraca 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 .

Nasłuchiwanie zdarzeń podrzędnych

Zdarzenia podrzędne są wywoływane w odpowiedzi na określone operacje wykonywane na dzieciach węzła, takie jak dodanie nowego dziecka za pomocą metody childByAutoId lub zaktualizowanie dziecka 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 dziecka, a następnie ponownie za każdym razem, gdy do określonej ścieżki dodawane jest nowe dziecko. Detektor otrzymuje migawkę zawierającą dane nowego dziecka.
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 podrzędnych węzła podrzędnego. Migawka przekazywana do detektora zdarzeń zawiera zaktualizowane dane dziecka.
FIRDataEventTypeChildRemoved Nasłuchiwanie elementów usuwanych z listy. To zdarzenie jest wywoływane, gdy usuwane jest bezpośrednie dziecko.Migawka przekazywana do bloku wywołania zwrotnego zawiera dane usuniętego dziecka.
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 dziecka. 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 celu 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 celu 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 jest zalecanym sposobem odczytywania list danych, ale w niektórych sytuacjach przydatne jest nasłuchiwanie zdarzeń wartości w odwołaniu do listy.

Dołączenie obserwatora FIRDataEventTypeValue do listy danych spowoduje zwrócenie całej listy danych jako pojedynczej migawki danych, którą możesz następnie przejrzeć, aby uzyskać dostęp do poszczególnych dzieci.

Nawet jeśli zapytanie znajdzie tylko 1 dopasowanie, migawka nadal będzie listą, tylko z 1 elementem. Aby uzyskać dostęp do elementu, musisz przejść przez wynik:

Swift

Uwaga: ta usługa Firebase nie jest dostępna w przypadku celu 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 celu 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 dzieci z listy w ramach jednej operacji, zamiast nasłuchiwać dodatkowych zdarzeń dodania dziecka.

Sortowanie i filtrowanie danych

Aby pobrać dane posortowane według klucza, wartości lub wartości dziecka, możesz użyć klasy Realtime Database FIRDatabaseQuery. Możesz też filtrować posortowany wynik, 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, która określi sposób sortowania wyników:

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

W danym momencie możesz użyć 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 celu 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 celu 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, posortowane 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 podrzędny, według którego mają być sortowane wyniki. W tym przykładzie posty są sortowane według wartości dziecka "starCount" w każdym poście. Zapytania można też sortować według zagnieżdżonych dzieci, 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 posortować elementy listy według wartości zagnieżdżonych pod kluczem metrics, określając ścieżkę względną do zagnieżdżonego dziecka w wywołaniu queryOrderedByChild.

Swift

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

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w przypadku celu App Clip.
 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"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
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ślonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
queryStartingAfterValue Zwraca elementy większe od określonego klucza lub wartości, w zależności od wybranej metody sortowania.
queryEndingAtValue Zwraca elementy mniejsze lub równe określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
queryEndingBeforeValue Zwraca elementy mniejsze od określonego klucza lub wartości, w zależności od wybranej metody sortowania.
queryEqualToValue 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 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ę dzieci, 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ą do 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 celu 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 celu 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 dziećmi, które mają określoną wartość.

Jak sortowane 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ę 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ą ciągu znaków jako kluczem, posortowane leksykograficznie w kolejności rosnącej.

queryOrderedByValue

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

queryOrderedByChild

Gdy używasz queryOrderedByChild, dane zawierające określony klucz podrzędny są sortowane w ten sposób:

  1. Najpierw pojawiają się dzieci z wartością nil dla określonego klucza podrzędnego.
  2. Następnie pojawiają się dzieci z wartością false dla określonego klucza podrzędnego przyjdź dalej. Jeśli kilka dzieci ma wartość false, są one sortowane leksykograficznie według klucza.
  3. Następnie pojawiają się dzieci z wartością true dla określonego klucza podrzędnego przyjdź dalej. Jeśli kilka dzieci ma wartość true, są one sortowane leksykograficznie według klucza.
  4. Następnie pojawiają się dzieci z wartością liczbową, posortowane w kolejności rosnącej. Jeśli kilka dzieci 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 dzieci ma tę samą wartość dla określonego węzła podrzędnego, są one sortowane leksykograficznie według klucza.
  6. Na końcu pojawiają się obiekty, posortowane leksykograficznie według klucza w kolejności rosnącej.

Odłączanie detektorów

Gdy opuszczasz ViewController, obserwatorzy nie przestają automatycznie synchronizować danych. Jeśli obserwator 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 obserwator 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 mogą służyć do usuwania 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 obserwatory w tej 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