Pobieranie elementu FIRDatabaseReference
Aby odczytywać lub zapisywać dane w bazie danych, potrzebujesz instancji FIRDatabaseReference:
Swift
var ref: DatabaseReference! ref = Database.database().reference()
Objective-C
@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 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 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 podrzędnych 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.
|
Wszystkie te metody mogą 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
// 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
// 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 odniesieniu do listy.
Dołączenie obserwatora 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 dopasowanie, migawka nadal będzie listą, tylko z 1 elementem. Aby uzyskać dostęp do elementu, musisz iterować po wyniku:
Swift
_commentsRef.observe(.value) { snapshot in for child in snapshot.children { ... } }
Objective-C
[_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 sortowania wyników:
| Metoda | Wykorzystanie |
|---|---|
queryOrderedByKey
| Sortowanie wyników według kluczy elementów podrzędnych. |
queryOrderedByValue |
Sortowanie wyników według wartości elementów podrzędnych. |
queryOrderedByChild |
Sortowanie 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ż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
// My top posts by number of stars let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")
Objective-C
// 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, posortowane według liczby gwiazdek otrzymanych przez każdy post. Ta technika używania identyfikatorów jako kluczy indeksu nazywa się zwielokrotnieniem wyjściowym 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ć sortowane 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ż sortować 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 posortować 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
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")
Objective-C
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, 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ś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ę 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, wywołanie zwrotne FIRDataEventTypeChildAdded jest wywoływane dla każdego elementu.
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 wynosiła 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
// 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
// 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 paginacji danych lub znajdowania elementów z elementami podrzędnymi o określonej wartości.
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.
- Najpierw wyświetlane są elementy podrzędne z kluczem, który można przeanalizować jako 32-bitową liczbę całkowitą, posortowane w kolejności rosnącej.
- Następnie wyświetlane są 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ą sortowane według ich wartości. Kryteria sortowania 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ą sortowane w ten sposób:
- Najpierw wyświetlane są elementy podrzędne z wartością
nildla określonego klucza elementu podrzędnego. - Następnie wyświetlane są elementy podrzędne z wartością
falsedla określonego klucza elementu podrzędnego przychodzą następne. Jeśli kilka elementów podrzędnych ma wartośćfalse, są one sortowane leksykograficznie według klucza. - Następnie wyświetlane są elementy podrzędne z wartością
truedla określonego klucza elementu podrzędnego przyjdź dalej. Jeśli kilka elementów podrzędnych ma wartośćtrue, są one sortowane leksykograficznie według klucza. - Następnie wyświetlane są 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.
- Ciągi znaków są wyświetlane po liczbach i sortowane 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 sortowane leksykograficznie według klucza.
- Obiekty są wyświetlane na końcu i sortowane 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 modułu obsługi zdarzeń, co może spowodować wycieki pamięci. Gdy obserwator nie jest już potrzebny, usuń go, przekazując powiązany element FIRDatabaseHandle do metody removeObserverWithHandle.
Gdy dodasz blok wywołania zwrotnego do odwołania, zwracany jest element 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. Musisz też śledzić te odwołania lub uchwyty, aby je usunąć.