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];
Listen lesen und schreiben
Daten an eine Datenliste 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. Wenn Sie diese automatisch generierten Schlüssel für jedes neue Element in der Liste verwenden, können mehrere Clients gleichzeitig untergeordnete Elemente am selben Speicherort hinzufügen, ohne dass Schreibkonflikte auftreten. Der von childByAutoId
generierte eindeutige Schlüssel basiert auf einem Zeitstempel. Daher werden Listenelemente automatisch chronologisch sortiert.
Mit der Referenz auf die neuen Daten, die von der Methode childByAutoId
zurückgegeben werden, können Sie den Wert des automatisch generierten Schlüssels des untergeordneten Elements abrufen oder Daten für das untergeordnete Element festlegen.
Wenn Sie getKey
auf eine childByAutoId
-Referenz anwenden, wird der automatisch generierte Schlüssel zurückgegeben.
Mit diesen automatisch generierten Schlüsseln können Sie die Flattening-Datenstruktur vereinfachen. Weitere Informationen finden Sie im Beispiel für die Datenfan-out-Funktion.
Auf untergeordnete Ereignisse warten
Untergeordnete Ereignisse werden als Reaktion auf bestimmte Vorgänge ausgelöst, die aus einem Vorgang für die untergeordneten Elemente eines Knotens erfolgen, z. B. ein neues untergeordnetes Element, das mit der Methode childByAutoId
hinzugefügt wird, oder ein untergeordnetes Element, das mit der Methode updateChildValues
aktualisiert wird.
Ereignistyp | Normale Nutzung |
---|---|
FIRDataEventTypeChildAdded |
Listen mit Elementen abrufen oder nach Elementen suchen, die einer Liste hinzugefügt wurden Dieses Ereignis wird einmal für jedes vorhandene untergeordnete Element ausgelöst und dann jedes Mal, wenn dem angegebenen Pfad ein neues untergeordnetes Element hinzugefügt wird. Dem Listener wird ein Snapshot mit den Daten des neuen Kindes übergeben. |
FIRDataEventTypeChildChanged |
Auf Änderungen an den Elementen in einer Liste achten Dieses Ereignis wird jedes Mal ausgelöst, wenn ein untergeordneter Knoten geändert wird. Dazu gehören auch alle Änderungen an Nachkommen des untergeordneten Knotens. Der an den Ereignis-Listener übergebene Snapshot enthält die aktualisierten Daten für das untergeordnete Element. |
FIRDataEventTypeChildRemoved |
Beobachten Sie, ob Elemente aus einer Liste entfernt werden. Dieses Ereignis wird ausgelöst, wenn ein unmittelbares untergeordnetes Element entfernt wird. Der an den Rückrufblock übergebene Snapshot enthält die Daten für das entfernte untergeordnete Element. |
FIRDataEventTypeChildMoved |
Beobachten von Änderungen an der Reihenfolge der Elemente in einer sortierten Liste
Dieses Ereignis wird ausgelöst, wenn ein Update eine Neuanordnung des untergeordneten Elements zur Folge hat. Sie wird für Daten verwendet, die nach queryOrderedByChild
oder queryOrderedByValue sortiert sind.
|
Diese Kombination kann nützlich sein, um Änderungen an einem bestimmten Knoten in einer Datenbank zu überwachen. In einer Blog-App für soziale Netzwerke können diese Methoden beispielsweise zusammen verwendet werden, um die Aktivität in den Kommentaren eines Beitrags zu überwachen, 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 Wertänderungen warten
Während das Warten auf untergeordnete Ereignisse die empfohlene Methode zum Lesen von Datenlisten ist, ist es in bestimmten Situationen sinnvoll, auf Wertereignisse in einer Listenreferenz zu warten.
Wenn Sie einen FIRDataEventTypeValue
-Beobachter an eine Datenliste anhängen, wird die gesamte Datenliste als einzelner DataSnapshot zurückgegeben, über den Sie dann auf einzelne untergeordnete Elemente zugreifen können.
Auch wenn es nur eine Übereinstimmung für die Suchanfrage gibt, ist der Snapshot immer eine Liste, die nur ein Element enthält. Um auf das Element zuzugreifen, musst du 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 zum Hinzufügen von untergeordneten Elementen 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 die sortierten Ergebnisse auch auf eine bestimmte Anzahl von Ergebnissen oder einen Bereich von Schlüsseln oder Werten begrenzen.
Daten sortieren
Wenn Sie sortierte Daten abrufen möchten, müssen Sie zuerst eine der Sortierungsmethoden angeben, um zu bestimmen, wie die Ergebnisse sortiert werden:
Methode | Nutzung |
---|---|
queryOrderedByKey
| Ergebnisse nach untergeordneten Schlüsseln sortieren |
queryOrderedByValue |
Sortieren Sie die Ergebnisse nach untergeordneten Werten. |
queryOrderedByChild |
Ergebnisse nach dem Wert eines bestimmten untergeordneten Schlüssels oder eines verschachtelten untergeordneten Pfads sortieren. |
Sie können jeweils nur eine Sortiermethode verwenden. Wird eine Sortiermethode mehrmals in derselben Abfrage aufgerufen, wird ein Fehler ausgegeben.
Im folgenden Beispiel wird gezeigt, wie du eine Liste der Top-Beiträge eines Nutzers abrufen kannst, 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 aus dem Pfad in der Datenbank basierend auf seiner Nutzer-ID ab, sortiert nach der Anzahl der Sterne, die jeder Beitrag erhalten hat. Diese Technik der Verwendung von IDs als Indexschlüssel wird als Daten-Fan-Out bezeichnet. Weitere Informationen dazu finden Sie unter Datenbank strukturieren.
Der Aufruf der Methode queryOrderedByChild
gibt den untergeordneten Schlüssel an, anhand dessen 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 geordnet 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 ordnen, 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
Wenn Sie Daten filtern möchten, können Sie beim Erstellen einer Abfrage eine beliebige der Methoden zum Begrenzen oder Bestimmen des Bereichs mit einer Sortiermethode kombinieren.
Methode | Nutzung |
---|---|
queryLimitedToFirst |
Legt die maximale Anzahl von Elementen fest, die ab dem Beginn 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 je nach ausgewählter Sortiermethode Elemente zurück, die größer oder gleich dem angegebenen Schlüssel oder Wert sind. |
queryStartingAfterValue |
Gibt je nach ausgewählter Sortiermethode Elemente zurück, die größer als der angegebene Schlüssel oder Wert sind. |
queryEndingAtValue |
Gibt je nach ausgewählter Sortiermethode Elemente zurück, die kleiner oder gleich dem angegebenen Schlüssel oder Wert sind. |
queryEndingBeforeValue |
Je nach ausgewählter Sortiermethode werden Elemente zurückgegeben, die kleiner als der angegebene Schlüssel oder Wert sind. |
queryEqualToValue |
Gibt je nach ausgewählter Sortiermethode Elemente zurück, die dem angegebenen Schlüssel oder Wert entsprechen. |
Im Gegensatz zu den Sortiermethoden 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 eine maximale Anzahl von untergeordneten Elementen festlegen, die für einen bestimmten Rückruf synchronisiert werden sollen. Wenn Sie beispielsweise mit queryLimitedToFirst
ein Limit von 100 festlegen, erhalten Sie anfangs nur bis zu 100 FIRDataEventTypeChildAdded
-Callbacks. Wenn in Ihrer Firebase-Datenbank weniger als 100 Elemente gespeichert sind, wird für jedes Element ein FIRDataEventTypeChildAdded
-Callback ausgelöst.
Wenn sich Artikel ändern, erhalten Sie FIRDataEventTypeChildAdded
Callbacks für Artikel, die in die Abfrage aufgenommen werden, und FIRDataEventTypeChildRemoved
Callbacks für Artikel, die daraus entfernt werden, sodass die Gesamtzahl bei 100 bleibt.
Im folgenden Beispiel wird gezeigt, 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. Das kann nützlich sein, um Daten zu paginarisieren oder Elemente mit untergeordneten Elementen mit einem bestimmten Wert zu finden.
So werden Abfragedaten geordnet
In diesem Abschnitt wird erläutert, wie Daten mit den einzelnen Sortierungsmethoden in der FIRDatabaseQuery
-Klasse sortiert werden.
queryOrderedByKey
Wenn Sie Ihre Daten mit queryOrderedByKey
sortieren, werden sie 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 untergeordnete Elemente mit einem Stringwert als Schlüssel, sortiert in aufsteigender lexikografischer Reihenfolge.
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
Bei Verwendung von queryOrderedByChild
werden Daten, die den angegebenen untergeordneten Schlüssel enthalten, so sortiert:
- Untergeordnete Elemente mit einem
nil
-Wert für den angegebenen untergeordneten Schlüssel werden zuerst angezeigt. - Als Nächstes kommen 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 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 nach Zahlen und werden alphabetisch in aufsteigender Reihenfolge sortiert. Wenn mehrere untergeordnete Elemente denselben Wert für den angegebenen untergeordneten Knoten haben, werden sie nach Schlüssel sortiert.
- Objekte kommen zuletzt und werden in aufsteigender Reihenfolge nach Schlüssel sortiert.
Listener trennen
Die Datensynchronisierung für Beobachter wird nicht automatisch beendet, wenn Sie eine ViewController
verlassen. Wenn ein Beobachter nicht richtig entfernt wird, werden weiterhin Daten mit dem lokalen Arbeitsspeicher synchronisiert und alle Objekte beibehalten, die im Ereignishandler-Schließung erfasst wurden. Dies kann zu Speicherlecks führen. Wenn ein Beobachter nicht mehr benötigt wird, entfernen Sie ihn, indem Sie das zugehörige FIRDatabaseHandle
-Objekt an die Methode removeObserverWithHandle
übergeben.
Wenn Sie einer Referenz einen Callback-Block hinzufügen, wird FIRDatabaseHandle
zurückgegeben.
Mit diesen Handles kannst du den Callback-Block 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 Speicherort beenden möchten, müssen Sie alle Beobachter an einem Speicherort entfernen, indem Sie die Methode removeAllObservers
aufrufen.
Wenn Sie removeObserverWithHandle
oder removeAllObservers
auf einen Listener anwenden, werden die bei den untergeordneten Knoten registrierten Listener nicht automatisch entfernt. Sie müssen diese Verweise oder Handles auch im Auge behalten, um sie zu entfernen.