Korzystanie z list danych na platformach Apple

Pobieranie odniesienia do bazy danych FIRDatabase

Aby odczytywać lub zapisywać dane w bazie danych, musisz mieć instancję FIRDatabaseReference:

Swift

Uwaga: ta usługa Firebase nie jest dostępna w miejscu docelowym wycinka aplikacji.
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

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

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

Czytanie i pisanie list

Dołączanie do listy danych

Aby dołączyć dane do listy w aplikacji wieloużytkownika, 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 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ę childByAutoId jest oparty na sygnaturze czasowej, 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 wydawcy podrzędnego lub ustawić dane dla elementu podrzędnego. Wywołanie funkcji getKey w przypadku odwołania childByAutoId zwraca klucz wygenerowany automatycznie.

Możesz użyć tych automatycznie wygenerowanych kluczy, aby uprościć strukturę danych. Więcej informacji znajdziesz w przykładzie rozpowszechniania danych.

Nasłuchiwanie zdarzeń podrzędnych

Zdarzenia podrzędne są wywoływane w odpowiedzi na określone operacje wykonywane na podrzędnych węzłach w ramach operacji, np. dodanie nowego podrzędnego węzła za pomocą metody childByAutoId lub zaktualizowanie podrzędnego węzła za pomocą metody updateChildValues.

Typ zdarzenia Typowe zastosowanie
FIRDataEventTypeChildAdded 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.
FIRDataEventTypeChildChanged 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 podany do odbiornika zdarzeń zawiera zaktualizowane dane dotyczące podrzędnego elementu.
FIRDataEventTypeChildRemoved 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.
FIRDataEventTypeChildMoved Słuchaj zmian kolejności elementów na liście uporządkowanej. To zdarzenie jest wywoływane za każdym razem, gdy aktualizacja powoduje zmianę kolejności podrzędnych. Jest używany z danymi uporządkowanymi według queryOrderedByChild lub queryOrderedByValue.

Każdy z nich może być przydatny 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:

Swift

Uwaga: ta usługa Firebase nie jest dostępna w miejscu docelowym wycinka 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
  )
})

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w miejscu docelowym wycinka 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];
 }];

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 FIRDataEventTypeValue do listy danych spowoduje zwrócenie całej listy danych jako pojedynczego obiektu DataSnapshot, który możesz przetworzyć w pętli, aby uzyskać dostęp do poszczególnych elementów.

Nawet wtedy, gdy zapytanie pasuje tylko do jednego elementu, snapshot jest nadal listą, ale zawiera tylko jeden element. Aby uzyskać dostęp do elementu, musisz wykonać pętlę na wyniku:

Swift

Uwaga: ta usługa Firebase nie jest dostępna w miejscu docelowym wycinka aplikacji.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w przypadku celu typu 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

Za pomocą klasy Realtime Database FIRDatabaseQuery możesz pobierać dane posortowane według klucza, wartości lub wartości elementu podrzędnego. Możesz też ograniczyć liczbę wyników do określonej liczby lub do 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
queryOrderedByKey Uporządkuj wyniki według kluczy podrzędnych.
queryOrderedByValue Porządkuj wyniki według wartości elementów podrzędnych.
queryOrderedByChild Uporządkuj wyniki według wartości określonego klucza podrzędnego lub ścieżki podrzędnej ujętej w nawiasach.

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:

Swift

Uwaga: ta usługa Firebase nie jest dostępna w miejscu docelowym wycinka aplikacji.
// 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 typu 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 z ścieżki w bazie danych na podstawie jego identyfikatora użytkownika i porządkuje je według liczby gwiazdek przypisanych do każdego z nich. Ta technika polegająca na używaniu identyfikatorów jako kluczy indeksu nazywana jest rozgałęzieniami danych. Więcej informacji na ten temat znajdziesz w artykule Uporządkowanie bazy danych.

Wywołanie metody queryOrderedByChild określa klucz podrzędny, według którego mają być posortowane wyniki. W tym przykładzie posty są sortowane według wartości atrybutu "starCount" w każdym poście. 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, podają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 miejscu docelowym wycinka aplikacji.
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

Objective-C

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

Więcej informacji o kolejności innych typów danych znajdziesz w artykule o kolejności danych w zapytaniach.

Filtrowanie danych

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

Metoda Wykorzystanie
queryLimitedToFirst Określa maksymalną liczbę elementów do zwrócenia z początku uporządkowanej listy wyników.
queryLimitedToLast Określa maksymalną liczbę elementów do zwrócenia z końca posortowanej listy wyników.
queryStartingAtValue 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.
queryStartingAfterValue Zwraca elementy, które są większe niż określony klucz lub wartość, w zależności od wybranej metody sortowania.
queryEndingAtValue Zwraca elementy, których klucz lub wartość jest mniejsza lub równa określonemu kluczowi lub wartości, w zależności od wybranej metody sortowania.
queryEndingBeforeValue Zwraca elementy, które są mniejsze niż określony klucz lub wartość, w zależności od wybranej metody sortowania.
queryEqualToValue 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 sortowania według kolejności można łączyć wiele funkcji ograniczeń lub zakresu. Możesz np. połączyć metody queryStartingAtValuequeryEndingAtValue, aby ograniczyć wyniki do określonego zakresu wartości.

Ograniczanie liczby wyników

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

Gdy elementy się zmieniają, otrzymujesz wywołania zwrotne FIRDataEventTypeChildAdded dla tych, które wpiszą zapytanie, oraz FIRDataEventTypeChildRemoved wywołań zwrotnych dla elementów, które z nich nie korzystają. Dzięki temu łączna liczba pozostaje na 100.

Ten 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 miejscu docelowym wycinka 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))!

Objective-C

Uwaga: ta usługa Firebase nie jest dostępna w miejscu docelowym wycinka 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];

Filtrowanie według klucza lub wartości

Aby wybrać dowolne punkty początkowe, końcowe i odpowiadające punkty w zapytaniach, możesz użyć parametrów queryStartingAtValue, queryStartingAfterValue, queryEndingAtValue, queryEndingBeforeValuequeryEqualToValue. Może to być przydatne do podziału danych na strony lub znajdowania elementów z podelementami o określonej wartości.

Sposób porządkowania danych zapytań

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

queryOrderedByKey

Gdy do sortowania danych używasz funkcji queryOrderedByKey, są one 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. Kolejne są elementy podrzędne z wartością ciągu znaków jako kluczem, posortowane leksykograficznie w kolejności rosnącej.

queryOrderedByValue

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

queryOrderedByChild

Gdy używasz zapytania queryOrderedByChild, 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 nil jest równa nil.
  2. Następne są elementy podrzędne z wartością false określonego klucza podrzędnego. Jeśli wiele elementów podrzędnych ma wartość false, są one sortowane alfabetycznie według klucza.
  3. Następne są elementy podrzędne z wartością true określonego klucza podrzędnego. 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.

Odłączanie słuchaczy

Obserwatorzy nie przerywają automatycznie synchronizowania danych, gdy opuszczasz ViewController. Jeśli obserwator nie zostanie prawidłowo usunięty, będzie nadal synchronizować dane z pamięci lokalnej i zachowywać wszystkie obiekty przechwycone w ramach funkcji obsługi zdarzenia, co może spowodować wycieki pamięci. Gdy obserwator nie jest już potrzebny, usuń go, przekazując powiązaną z nim wartość FIRDatabaseHandle do metody removeObserverWithHandle.

Gdy dodasz do odwołania blok wywołania zwrotnego, zwrócony zostanie element FIRDatabaseHandle. Za pomocą tych uchwytów można usunąć blok wywołania zwrotnego.

Jeśli do odwołania do bazy danych dodano wielu detektorów, każdy z nich jest wywoływany po wystąpieniu zdarzenia. Aby zatrzymać synchronizację danych w tej lokalizacji, musisz usunąć wszystkich obserwatorów w tej lokalizacji, wywołując metodę removeAllObservers.

Wywołanie metody removeObserverWithHandle lub removeAllObservers na słuchaczu nie powoduje automatycznego usunięcia słuchaczy zarejestrowanych w węzłach podrzędnych. Musisz też śledzić te odwołania lub uchwyty, aby je usunąć.

Następne kroki