FIRDatabaseReference abrufen
Zum Lesen oder Schreiben von Daten aus der Datenbank benötigen Sie eine Instanz von FIRDatabaseReference:
Swift
var ref: DatabaseReference! ref = Database.database().reference()
Objective-C
@property (strong, nonatomic) FIRDatabaseReference *ref; self.ref = [[FIRDatabase database] reference];
Lese- und Schreiblisten
An eine Liste von Daten anhängen
Verwenden Sie die Methode childByAutoId, um Daten an eine Liste in Mehrbenutzeranwendungen anzuhängen. Die Methode childByAutoId generiert jedes Mal einen eindeutigen Schlüssel, wenn der angegebenen Firebase-Referenz ein neues untergeordnetes Element hinzugefügt wird. Durch die Verwendung dieser automatisch generierten Schlüssel für jedes neue Element in der Liste können mehrere Clients gleichzeitig untergeordnete Elemente am selben Speicherort hinzufügen, ohne dass es zu Schreibkonflikten kommt. Der von childByAutoId generierte eindeutige Schlüssel basiert auf einem Zeitstempel, sodass Listenelemente automatisch chronologisch sortiert werden.
Sie können den Verweis auf die neuen Daten, die von der Methode childByAutoId zurückgegeben werden, verwenden, um den Wert des automatisch generierten Schlüssels des untergeordneten Elements abzurufen oder Daten für das untergeordnete Element festzulegen.
Wenn Sie getKey für eine childByAutoId-Referenz aufrufen, wird der automatisch generierte Schlüssel zurückgegeben.
Sie können diese automatisch generierten Schlüssel verwenden, um die Vereinfachung Ihrer Datenstruktur zu vereinfachen. Weitere Informationen finden Sie im Beispiel für die Datenverteilung.
Auf untergeordnete Ereignisse warten
Untergeordnete Ereignisse werden als Reaktion auf bestimmte Vorgänge ausgelöst, die für die untergeordneten Elemente eines Knotens ausgeführt werden, z. B. wenn ein neues untergeordnetes Element über die Methode childByAutoId hinzugefügt oder ein untergeordnetes Element über die Methode updateChildValues aktualisiert wird.
| Ereignistyp | Typische Verwendung |
|---|---|
FIRDataEventTypeChildAdded |
Listen mit Elementen abrufen oder auf Ergänzungen zu einer Liste mit Elementen warten. Dieses Ereignis wird einmal für jedes vorhandene untergeordnete Element und dann jedes Mal ausgelöst, wenn dem angegebenen Pfad ein neues untergeordnetes Element hinzugefügt wird. An den Listener wird ein Snapshot mit den Daten des neuen untergeordneten Elements übergeben. |
FIRDataEventTypeChildChanged |
Änderungen an den Elementen in einer Liste beobachten. Dieses Ereignis wird ausgelöst, wenn ein untergeordneter Knoten geändert wird. Dies schließt alle Änderungen an untergeordneten Elementen des untergeordneten Knotens ein. Der an den Ereignis-Listener übergebene Snapshot enthält die aktualisierten Daten für das untergeordnete Element. |
FIRDataEventTypeChildRemoved |
Auf das Entfernen von Elementen aus einer Liste warten. Dieses Ereignis wird ausgelöst, wenn ein direktes untergeordnetes Element entfernt wird.Der an den Callback-Block übergebene Snapshot enthält die Daten für das entfernte untergeordnete Element. |
FIRDataEventTypeChildMoved |
Änderungen an der Reihenfolge der Elemente in einer sortierten Liste überwachen.
Dieses Ereignis wird immer dann ausgelöst, wenn ein Update dazu führt, dass das untergeordnete Element neu angeordnet wird. Sie wird für Daten verwendet, die nach queryOrderedByChild
oder queryOrderedByValue sortiert sind.
|
Beide zusammen können nützlich sein, um auf Änderungen an einem bestimmten Knoten in einer Datenbank zu warten. Eine Social-Blogging-App könnte diese Methoden beispielsweise zusammen verwenden, um die Aktivität in den Kommentaren eines Beitrags zu beobachten, wie unten gezeigt:
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]; }];
Auf Wertereignisse warten
Das Abhören von untergeordneten Ereignissen ist zwar die empfohlene Methode zum Lesen von Datenlisten, aber es gibt Situationen, in denen das Abhören von Wertereignissen für eine Listenreferenz nützlich ist.
Wenn Sie einen FIRDataEventTypeValue-Beobachter an eine Liste von Daten anhängen, wird die gesamte Liste als einzelner DataSnapshot zurückgegeben, den Sie dann durchlaufen können, um auf einzelne untergeordnete Elemente zuzugreifen.
Auch wenn es nur eine einzige Übereinstimmung für die Abfrage gibt, ist der Snapshot immer noch eine Liste, die nur ein einziges Element enthält. Um auf das Element zuzugreifen, müssen Sie das Ergebnis durchlaufen:
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]) { // ... } }];
Dieses Muster kann nützlich sein, wenn Sie alle untergeordneten Elemente einer Liste in einem einzigen Vorgang abrufen möchten, anstatt auf zusätzliche Ereignisse für hinzugefügte untergeordnete Elemente zu warten.
Daten sortieren und filtern
Mit der Klasse Realtime Database FIRDatabaseQuery können Sie Daten abrufen, die nach Schlüssel, Wert oder Wert eines untergeordneten Elements sortiert sind. Sie können das sortierte Ergebnis auch auf eine bestimmte Anzahl von Ergebnissen oder einen Bereich von Schlüsseln oder Werten filtern.
Daten sortieren
Wenn Sie sortierte Daten abrufen möchten, geben Sie zuerst eine der order by-Methoden an, um festzulegen, wie die Ergebnisse sortiert werden sollen:
| Methode | Nutzung |
|---|---|
queryOrderedByKey
| Ergebnisse nach untergeordneten Schlüsseln sortieren. |
queryOrderedByValue |
Ergebnisse nach untergeordneten Werten sortieren. |
queryOrderedByChild |
Ergebnisse nach dem Wert eines angegebenen untergeordneten Schlüssels oder verschachtelten untergeordneten Pfads sortieren. |
Sie können jeweils nur eine order by-Methode verwenden. Wenn eine order by-Methode mehrmals in derselben Abfrage aufgerufen wird, wird ein Fehler ausgegeben.
Im folgenden Beispiel wird gezeigt, wie Sie eine Liste der Top-Beiträge eines Nutzers abrufen können, sortiert nach der Anzahl der Sterne:
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"];
Diese Abfrage ruft die Beiträge des Nutzers anhand seiner Nutzer-ID aus dem Pfad in der Datenbank ab, sortiert nach der Anzahl der Sterne, die jeder Beitrag erhalten hat. Diese Technik, IDs als Indexschlüssel zu verwenden, wird als Daten-Fan-out bezeichnet. Weitere Informationen dazu finden Sie unter Datenbank strukturieren.
Beim Aufruf der Methode queryOrderedByChild wird der untergeordnete Schlüssel angegeben, nach dem die Ergebnisse sortiert werden sollen. In diesem Beispiel werden die Beiträge nach dem Wert des untergeordneten "starCount"-Elements in jedem Beitrag sortiert. Abfragen können auch nach verschachtelten untergeordneten Elementen sortiert werden, wenn Sie Daten wie die folgenden haben:
"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",
}
},In diesem Fall können wir die Listenelemente nach Werten sortieren, die unter dem Schlüssel metrics verschachtelt sind. Dazu geben wir den relativen Pfad zum verschachtelten untergeordneten Element im queryOrderedByChild-Aufruf an.
Swift
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")
Objective-C
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];
Weitere Informationen zur Sortierung anderer Datentypen finden Sie unter Sortierung von Abfragedaten.
Daten filtern
Wenn Sie Daten filtern möchten, können Sie beim Erstellen einer Abfrage eine beliebige Limit- oder Bereichsmethode mit einer order by-Methode kombinieren.
| Methode | Nutzung |
|---|---|
queryLimitedToFirst |
Legt die maximale Anzahl von Elementen fest, die ab dem Anfang der sortierten Ergebnisliste zurückgegeben werden sollen. |
queryLimitedToLast |
Legt die maximale Anzahl der Elemente fest, die vom Ende der sortierten Ergebnisliste zurückgegeben werden sollen. |
queryStartingAtValue |
Gibt Elemente zurück, die größer oder gleich dem angegebenen Schlüssel oder Wert sind, je nach gewählter order by-Methode. |
queryStartingAfterValue |
Gibt Elemente zurück, die größer als der angegebene Schlüssel oder Wert sind, je nach ausgewählter order by-Methode. |
queryEndingAtValue |
Gibt Elemente zurück, die kleiner oder gleich dem angegebenen Schlüssel oder Wert sind, je nach gewählter order by-Methode. |
queryEndingBeforeValue |
Gibt Elemente zurück, die kleiner als der angegebene Schlüssel oder Wert sind, je nach gewählter order by-Methode. |
queryEqualToValue |
Gibt Elemente zurück, die dem angegebenen Schlüssel oder Wert entsprechen, je nach ausgewählter order by-Methode. |
Im Gegensatz zu den order by-Methoden können Sie mehrere Limit- oder Bereichsfunktionen kombinieren.
Sie können beispielsweise die Methoden queryStartingAtValue und queryEndingAtValue kombinieren, um die Ergebnisse auf einen bestimmten Wertebereich zu beschränken.
Anzahl der Ergebnisse begrenzen
Mit den Methoden queryLimitedToFirst und queryLimitedToLast können Sie die maximale Anzahl von untergeordneten Elementen festlegen, die für einen bestimmten Callback synchronisiert werden sollen. Wenn Sie beispielsweise mit queryLimitedToFirst ein Limit von 100 festlegen, erhalten Sie anfangs nur bis zu 100 FIRDataEventTypeChildAdded-Callbacks. Wenn weniger als 100 Elemente in Ihrer Firebase-Datenbank gespeichert sind, wird für jedes Element ein FIRDataEventTypeChildAdded-Callback ausgelöst.
Wenn sich Elemente ändern, erhalten Sie FIRDataEventTypeChildAdded-Callbacks für Elemente, die in die Abfrage aufgenommen werden, und FIRDataEventTypeChildRemoved-Callbacks für Elemente, die aus der Abfrage entfernt werden, sodass die Gesamtzahl bei 100 bleibt.
Das folgende Beispiel zeigt, wie eine Beispiel-Blogging-App eine Liste der 100 neuesten Beiträge aller Nutzer abrufen könnte:
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];
Nach Schlüssel oder Wert filtern
Mit queryStartingAtValue, queryStartingAfterValue, queryEndingAtValue, queryEndingBeforeValue und queryEqualToValue können Sie beliebige Start-, End- und Äquivalenzpunkte für Abfragen auswählen. Dies kann nützlich sein, um Daten zu paginieren oder Elemente mit untergeordneten Elementen zu finden, die einen bestimmten Wert haben.
So werden Abfragedaten sortiert
In diesem Abschnitt wird erläutert, wie Daten nach den einzelnen order-by-Methoden in der Klasse FIRDatabaseQuery sortiert werden.
queryOrderedByKey
Wenn Sie queryOrderedByKey zum Sortieren Ihrer Daten verwenden, werden die Daten in aufsteigender Reihenfolge nach Schlüssel zurückgegeben.
- Untergeordnete Elemente mit einem Schlüssel, der als 32-Bit-Ganzzahl geparst werden kann, werden zuerst angezeigt, sortiert in aufsteigender Reihenfolge.
- Als Nächstes folgen untergeordnete Elemente mit einem Stringwert als Schlüssel, die lexikografisch in aufsteigender Reihenfolge sortiert sind.
queryOrderedByValue
Bei Verwendung von queryOrderedByValue werden untergeordnete Elemente nach ihrem Wert sortiert. Die Sortierkriterien sind dieselben wie in queryOrderedByChild, mit der Ausnahme, dass der Wert des Knotens anstelle des Werts eines angegebenen untergeordneten Schlüssels verwendet wird.
queryOrderedByChild
Wenn Sie queryOrderedByChild verwenden, werden Daten, die den angegebenen untergeordneten Schlüssel enthalten, so sortiert:
- Untergeordnete Elemente mit dem Wert
nilfür den angegebenen untergeordneten Schlüssel stehen an erster Stelle. - Als Nächstes folgen untergeordnete Elemente mit dem Wert
falsefür den angegebenen untergeordneten Schlüssel. Wenn mehrere untergeordnete Elemente den Wertfalsehaben, werden sie lexikografisch nach Schlüssel sortiert. - Als Nächstes folgen untergeordnete Elemente mit dem Wert
truefür den angegebenen untergeordneten Schlüssel. Wenn mehrere untergeordnete Elemente den Werttruehaben, werden sie lexikografisch nach Schlüssel sortiert. - Als Nächstes folgen untergeordnete Elemente mit einem numerischen Wert, sortiert in aufsteigender Reihenfolge. Wenn mehrere untergeordnete Elemente denselben numerischen Wert für den angegebenen untergeordneten Knoten haben, werden sie nach Schlüssel sortiert.
- Strings werden nach Zahlen aufgeführt und lexikografisch in aufsteigender Reihenfolge sortiert. Wenn mehrere untergeordnete Elemente denselben Wert für den angegebenen untergeordneten Knoten haben, werden sie lexikografisch nach Schlüssel sortiert.
- Objekte kommen zuletzt und werden lexikografisch nach Schlüssel in aufsteigender Reihenfolge sortiert.
Listener trennen
Beobachter beenden die Datensynchronisierung nicht automatisch, wenn Sie eine ViewController verlassen. Wenn ein Beobachter nicht ordnungsgemäß entfernt wird, werden weiterhin Daten mit dem lokalen Speicher synchronisiert und alle Objekte, die im Event-Handler-Closure erfasst wurden, werden beibehalten. Dies kann zu Speicherlecks führen. Wenn ein Beobachter nicht mehr benötigt wird, entfernen Sie ihn, indem Sie die zugehörige FIRDatabaseHandle an die Methode removeObserverWithHandle übergeben.
Wenn Sie einer Referenz einen Callback-Block hinzufügen, wird ein FIRDatabaseHandle zurückgegeben.
Diese Handles können verwendet werden, um den Callback-Block zu entfernen.
Wenn einer Datenbankreferenz mehrere Listener hinzugefügt wurden, wird jeder Listener aufgerufen, wenn ein Ereignis ausgelöst wird. Wenn Sie die Synchronisierung von Daten an diesem Standort beenden möchten, müssen Sie alle Beobachter an einem Standort entfernen. Rufen Sie dazu die Methode removeAllObservers auf.
Wenn Sie removeObserverWithHandle oder removeAllObservers für einen Listener aufrufen, werden Listener, die für die untergeordneten Knoten registriert sind, nicht automatisch entfernt. Sie müssen diese Verweise oder Handles ebenfalls im Blick behalten, um sie zu entfernen.