FIRDatabaseReference abrufen
Wenn Sie Daten aus der Datenbank lesen oder in die Datenbank schreiben möchten, 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];
Listen lesen und schreiben
An eine Liste mit Daten anhängen
Verwenden Sie die Methode childByAutoId
, um Daten an eine Liste in Anwendungen mit mehreren Nutzern 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 Ort hinzufügen, ohne dass es zu Schreibkonflikten kommt. Der von childByAutoId
generierte eindeutige Schlüssel basiert auf einem Zeitstempel. Die Listenelemente werden also automatisch chronologisch sortiert.
Sie können mit dem Verweis auf die neuen Daten, die von der Methode childByAutoId
zurückgegeben werden, den Wert des automatisch generierten Schlüssels des untergeordneten Elements abrufen oder Daten für das untergeordnete Element festlegen.
Wenn Sie getKey
für eine childByAutoId
-Referenz aufrufen, wird der automatisch generierte Schlüssel zurückgegeben.
Mit diesen automatisch generierten Schlüsseln können Sie die Datenstruktur vereinfachen. Weitere Informationen finden Sie im Beispiel für das Fan-out von Daten.
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 von Elementen abrufen oder auf Ergänzungen einer Liste von 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. Dem Listener wird ein Snapshot mit den Daten des neuen untergeordneten Elements übergeben. |
FIRDataEventTypeChildChanged |
Änderungen an den Elementen in einer Liste beobachten Dieses Ereignis wird immer dann ausgelöst, wenn ein untergeordneter Knoten geändert wird. Das gilt auch für alle Änderungen an untergeordneten Knoten des untergeordneten Knotens. Der Snapshot, der an den Ereignis-Listener übergeben wird, enthält die aktualisierten Daten für das untergeordnete Element. |
FIRDataEventTypeChildRemoved |
Auf das Entfernen von Elementen aus einer Liste reagieren Dieses Ereignis wird ausgelöst, wenn ein untergeordnetes Element entfernt wird.Der Snapshot, der an den Callback-Block übergeben wird, enthält die Daten für das entfernte untergeordnete Element. |
FIRDataEventTypeChildMoved |
Auf Änderungen der Reihenfolge von Elementen in einer sortierten Liste reagieren
Dieses Ereignis wird immer dann ausgelöst, wenn durch ein Update die Reihenfolge des untergeordneten Elements geändert wird. Sie wird für Daten verwendet, die nach queryOrderedByChild
oder queryOrderedByValue sortiert sind.
|
Jede dieser Methoden kann nützlich sein, um Änderungen an einem bestimmten Knoten in einer Datenbank zu beobachten. Eine Social-Blogging-App kann diese Methoden beispielsweise zusammen verwenden, um Aktivitäten in den Kommentaren eines Beitrags zu überwachen, wie unten dargestellt:
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 Wert-Ereignisse warten
Das Beobachten von untergeordneten Ereignissen ist zwar die empfohlene Methode zum Lesen von Datenlisten, es gibt jedoch Situationen, in denen das Beobachten von Wertänderungen für eine Listenreferenz nützlich ist.
Wenn Sie einen FIRDataEventTypeValue
-Observer an eine Liste von Daten anhängen, wird die gesamte Liste von Daten als einzelner DataSnapshot zurückgegeben, den Sie dann durchlaufen können, um auf einzelne untergeordnete Elemente zuzugreifen.
Auch wenn es nur eine Übereinstimmung für die Anfrage gibt, ist der Snapshot weiterhin eine Liste, die nur ein 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 vom Typ „child added“ zu warten.
Daten sortieren und filtern
Mit der Klasse Realtime Database FIRDatabaseQuery
können Sie Daten abrufen, die nach Schlüssel, Wert oder dem Wert eines untergeordneten Elements sortiert sind. Sie können das sortierte Ergebnis auch nach einer bestimmten Anzahl von Ergebnissen oder einem 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 die Reihenfolge der Ergebnisse festzulegen:
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 eines verschachtelten untergeordneten Pfads sortieren. |
Sie können jeweils nur eine Order-by-Methode verwenden. Wenn Sie eine „order-by“-Methode mehrmals in derselben Abfrage aufrufen, wird ein Fehler ausgegeben.
Im folgenden Beispiel wird gezeigt, wie Sie eine Liste der Top-Beiträge eines Nutzers abrufen, 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"];
Mit dieser Abfrage werden die Beiträge des Nutzers aus dem Pfad in der Datenbank abgerufen, basierend auf seiner Nutzer-ID und sortiert nach der Anzahl der Sterne, die jeder Beitrag erhalten hat. Diese Technik, IDs als Indexschlüssel zu verwenden, wird als „Data Fan-Out“ bezeichnet. Weitere Informationen dazu finden Sie unter Datenbank strukturieren.
Mit dem Aufruf der Methode queryOrderedByChild
wird der untergeordnete Schlüssel angegeben, nach dem die Ergebnisse sortiert werden sollen. In diesem Beispiel werden Beiträge nach dem Wert des untergeordneten Elements "starCount"
in jedem Beitrag sortiert. Abfragen können auch nach verschachtelten untergeordneten Elementen sortiert werden, wenn Sie Daten haben, die so aussehen:
"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 unsere Listenelemente nach Werten sortieren, die unter dem Schlüssel metrics
verschachtelt sind. Dazu geben wir den relativen Pfad zum verschachtelten untergeordneten Element in unserem 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
Um Daten zu filtern, können Sie beim Erstellen einer Abfrage eine beliebige der Limit- oder Bereichsmethoden mit einer Order-by-Methode kombinieren.
Methode | Nutzung |
---|---|
queryLimitedToFirst |
Legt die maximale Anzahl der Elemente 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 ausgewählter Sortiermethode. |
queryStartingAfterValue |
Gibt Elemente zurück, die größer als der angegebene Schlüssel oder Wert sind, je nach gewählter „order-by“-Methode. |
queryEndingAtValue |
Gibt Elemente zurück, die kleiner oder gleich dem angegebenen Schlüssel oder Wert sind, je nach ausgewählter Sortiermethode. |
queryEndingBeforeValue |
Gibt Elemente zurück, die kleiner als der angegebene Schlüssel oder Wert sind, je nach ausgewählter Sortierungsmethode. |
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 Range-Funktionen 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 eine 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 Sie weniger als 100 Elemente in Ihrer Firebase-Datenbank gespeichert haben, 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. Die Gesamtzahl bleibt dabei immer bei 100.
Das folgende Beispiel zeigt, wie eine Beispiel-Blogging-App eine Liste der 100 neuesten Beiträge aller Nutzer abrufen kann:
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. Das 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 mit 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 in aufsteigender Reihenfolge sortiert.
- Als Nächstes folgen Kinder 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:
- Kinder mit einem
nil
-Wert für den angegebenen untergeordneten Schlüssel werden zuerst angezeigt. - Als Nächstes folgen untergeordnete Elemente mit dem Wert
false
für den angegebenen untergeordneten Schlüssel. Wenn mehrere untergeordnete Elemente den Wertfalse
haben, werden sie lexikografisch nach Schlüssel sortiert. - Als Nächstes folgen untergeordnete Elemente mit dem Wert
true
für den angegebenen untergeordneten Schlüssel. Wenn mehrere untergeordnete Elemente den Werttrue
haben, 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 folgen auf Zahlen und werden 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 werden zuletzt angezeigt und lexikografisch nach Schlüssel in aufsteigender Reihenfolge sortiert.
Listener trennen
Die Synchronisierung von Daten wird nicht automatisch beendet, wenn Sie eine ViewController
verlassen. Wenn ein Observer nicht richtig entfernt wird, werden weiterhin Daten mit dem lokalen Speicher synchronisiert und alle im Event-Handler-Closure erfassten Objekte bleiben erhalten, was zu Speicherlecks führen kann. Wenn ein Observer nicht mehr benötigt wird, entfernen Sie ihn, indem Sie das zugehörige FIRDatabaseHandle
an die Methode removeObserverWithHandle
übergeben.
Wenn Sie einer Referenz einen Callback-Block hinzufügen, wird FIRDatabaseHandle
zurückgegeben.
Mit diesen Handles kann der Callback-Block entfernt werden.
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 Speicherort beenden möchten, müssen Sie alle Beobachter an einem Speicherort entfernen. Rufen Sie dazu die Methode removeAllObservers
auf.
Wenn Sie removeObserverWithHandle
oder removeAllObservers
für einen Listener aufrufen, werden Listener, die in den untergeordneten Knoten registriert sind, nicht automatisch entfernt. Sie müssen diese Referenzen oder Handles auch im Blick behalten, um sie zu entfernen.