Rufen Sie eine FIRDatabaseReference ab
Um Daten aus der Datenbank zu lesen oder zu schreiben, benötigen Sie eine Instanz von FIRDatabaseReference
:
Schnell
var ref: DatabaseReference! ref = Database.database().reference()
Ziel c
@property (strong, nonatomic) FIRDatabaseReference *ref; self.ref = [[FIRDatabase database] reference];
Listen lesen und schreiben
An eine Datenliste anhängen
Verwenden Sie die Methode childByAutoId
, um in Mehrbenutzeranwendungen Daten an eine Liste anzuhängen. Die Methode childByAutoId
generiert jedes Mal einen eindeutigen Schlüssel, wenn der angegebenen Firebase-Referenz ein neues Kind hinzugefügt wird. Durch die Verwendung dieser automatisch generierten Schlüssel für jedes neue Element in der Liste können mehrere Clients gleichzeitig Kinder an derselben Position 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. Der Aufruf von getKey
für eine childByAutoId
Referenz gibt den automatisch generierten Schlüssel zurück.
Sie können diese automatisch generierten Schlüssel verwenden, um die Reduzierung Ihrer Datenstruktur zu vereinfachen. Weitere Informationen finden Sie im Daten-Fanout- Beispiel .
Achten Sie auf untergeordnete Ereignisse
Untergeordnete Ereignisse werden als Reaktion auf bestimmte Vorgänge ausgelöst, die für die untergeordneten Elemente eines Knotens durch einen Vorgang ausgeführt werden, z. B. ein neues untergeordnetes Element, das über die Methode childByAutoId
hinzugefügt wird, oder ein untergeordnetes Element, das über die Methode updateChildValues
aktualisiert wird.
Ereignistyp | Typische Verwendung |
---|---|
FIRDataEventTypeChildAdded | Rufen Sie Artikellisten ab oder warten Sie auf Ergänzungen zu einer Artikelliste. Dieses Ereignis wird einmal für jedes vorhandene untergeordnete Element und jedes Mal erneut ausgelöst, wenn dem angegebenen Pfad ein neues untergeordnetes Element hinzugefügt wird. Dem Listener wird ein Snapshot übergeben, der die Daten des neuen untergeordneten Elements enthält. |
FIRDataEventTypeChildChanged | Achten Sie auf Änderungen an den Elementen in einer Liste. Dieses Ereignis wird jedes Mal ausgelöst, wenn ein untergeordneter Knoten geändert wird. Dazu gehören 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 | Achten Sie auf Elemente, die aus einer Liste entfernt werden. Dieses Ereignis wird ausgelöst, wenn ein unmittelbar untergeordnetes Element entfernt wird. Der an den Rückrufblock übergebene Snapshot enthält die Daten für das entfernte untergeordnete Element. |
FIRDataEventTypeChildMoved | Achten Sie auf Änderungen in der Reihenfolge der Elemente in einer geordneten Liste. Dieses Ereignis wird immer dann ausgelöst, wenn eine Aktualisierung eine Neuordnung des untergeordneten Elements verursacht. Es wird mit Daten verwendet, die nach queryOrderedByChild oder queryOrderedByValue geordnet sind. |
Beides zusammen kann nützlich sein, um Änderungen an einem bestimmten Knoten in einer Datenbank abzuhören. Beispielsweise könnte eine Social-Blogging-App diese Methoden zusammen verwenden, um die Aktivität in den Kommentaren eines Beitrags zu überwachen, wie unten gezeigt:
Schnell
// 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 ) })
Ziel 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]; }];
Achten Sie auf Wertereignisse
Während die Überwachung auf untergeordnete Ereignisse die empfohlene Methode zum Lesen von Datenlisten ist, gibt es Situationen, in denen die Überwachung auf Wertereignisse in einer Listenreferenz nützlich ist.
Wenn Sie einen FIRDataEventTypeValue
Beobachter an eine Datenliste anhängen, wird die gesamte Datenliste als einzelner DataSnapshot zurückgegeben, den Sie dann durchlaufen können, um auf einzelne untergeordnete Elemente zuzugreifen.
Selbst wenn es nur eine einzige Übereinstimmung für die Abfrage gibt, ist der Snapshot immer noch eine Liste; es enthält nur ein einzelnes Element. Um auf das Element zuzugreifen, müssen Sie das Ergebnis durchlaufen:
Schnell
_commentsRef.observe(.value) { snapshot in for child in snapshot.children { ... } }
Ziel 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 untergeordnete hinzugefügte Ereignisse zu warten.
Daten sortieren und filtern
Sie können die Realtime Database FIRDatabaseQuery
Klasse verwenden, um nach Schlüssel, Wert oder Wert eines untergeordneten Elements sortierte Daten abzurufen. Sie können das sortierte Ergebnis auch nach einer bestimmten Anzahl von Ergebnissen oder einem Bereich von Schlüsseln oder Werten filtern.
Daten sortieren
Um sortierte Daten abzurufen, geben Sie zunächst eine der Order-by-Methoden an, um zu bestimmen, wie die Ergebnisse sortiert werden:
Methode | Verwendung |
---|---|
queryOrderedByKey | Sortieren Sie die Ergebnisse nach untergeordneten Schlüsseln. |
queryOrderedByValue | Sortieren Sie die Ergebnisse nach untergeordneten Werten. |
queryOrderedByChild | Ordnen Sie die Ergebnisse nach dem Wert eines angegebenen untergeordneten Schlüssels oder eines verschachtelten untergeordneten Pfads. |
Sie können jeweils nur eine Order-By-Methode verwenden. Der mehrmalige Aufruf einer Order-By-Methode in derselben Abfrage führt zu einem Fehler.
Das folgende Beispiel zeigt, wie Sie eine Liste der Top-Beiträge eines Benutzers, sortiert nach der Anzahl der Sterne, abrufen können:
Schnell
// My top posts by number of stars let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")
Ziel 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 Benutzers aus dem Pfad in der Datenbank basierend auf seiner Benutzer-ID ab, geordnet nach der Anzahl der Sterne, die jeder Beitrag erhalten hat. Diese Technik, bei der IDs als Indexschlüssel verwendet werden, wird als Daten-Fan-Out bezeichnet. Weitere Informationen dazu finden Sie unter „Strukturieren Sie Ihre Datenbank“ .
Der Aufruf der Methode queryOrderedByChild
gibt den untergeordneten Schlüssel an, nach dem die Ergebnisse sortiert werden sollen. In diesem Beispiel werden die Beiträge nach dem Wert des untergeordneten Elements "starCount"
in jedem Beitrag sortiert. Abfragen können auch nach verschachtelten untergeordneten Elementen sortiert werden, falls Sie Daten haben, die wie folgt 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 unter dem metrics
verschachtelten Werten ordnen, indem wir in unserem queryOrderedByChild
Aufruf den relativen Pfad zum verschachtelten untergeordneten Element angeben.
Schnell
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")
Ziel c
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];
Weitere Informationen zur Reihenfolge anderer Datentypen finden Sie unter Reihenfolge der Abfragedaten .
Daten filtern
Um Daten zu filtern, können Sie beim Erstellen einer Abfrage jede der Limit- oder Range-Methoden mit einer Order-by-Methode kombinieren.
Methode | Verwendung |
---|---|
queryLimitedToFirst | Legt die maximale Anzahl von Elementen fest, die vom Anfang der geordneten Ergebnisliste zurückgegeben werden sollen. |
queryLimitedToLast | Legt die maximale Anzahl von Elementen fest, die vom Ende der geordneten Ergebnisliste zurückgegeben werden sollen. |
queryStartingAtValue | Gibt Elemente zurück, die größer oder gleich dem angegebenen Schlüssel oder Wert sind, abhängig von der gewählten Sortiermethode. |
queryStartingAfterValue | Gibt Elemente zurück, die größer als der angegebene Schlüssel oder Wert sind, abhängig von der gewählten Sortiermethode. |
queryEndingAtValue | Gibt Elemente zurück, die kleiner oder gleich dem angegebenen Schlüssel oder Wert sind, abhängig von der gewählten Sortiermethode. |
queryEndingBeforeValue | Gibt Elemente zurück, die kleiner als der angegebene Schlüssel oder Wert sind, abhängig von der gewählten Sortiermethode. |
queryEqualToValue | Gibt Elemente zurück, die dem angegebenen Schlüssel oder Wert entsprechen, abhängig von der gewählten Sortiermethode. |
Im Gegensatz zu den Order-by-Methoden können Sie mehrere Grenzwert- oder Bereichsfunktionen kombinieren. Beispielsweise können Sie die Methoden queryStartingAtValue
und queryEndingAtValue
kombinieren, um die Ergebnisse auf einen angegebenen Wertebereich zu beschränken.
Begrenzen Sie die Anzahl der Ergebnisse
Sie können die Methoden queryLimitedToFirst
und queryLimitedToLast
verwenden, um eine maximale Anzahl von untergeordneten Elementen festzulegen, die für einen bestimmten Rückruf synchronisiert werden sollen. Wenn Sie beispielsweise mit queryLimitedToFirst
einen Grenzwert von 100 festlegen, erhalten Sie zunächst nur bis zu 100 FIRDataEventTypeChildAdded
Rückrufe. Wenn in Ihrer Firebase-Datenbank weniger als 100 Elemente gespeichert sind, wird für jedes Element ein FIRDataEventTypeChildAdded
Rückruf ausgelöst.
Wenn sich Elemente ändern, erhalten Sie FIRDataEventTypeChildAdded
Rückrufe für Elemente, die in die Abfrage eingegeben werden, und FIRDataEventTypeChildRemoved
-Rückrufe für Elemente, die aus der Abfrage herausfallen, sodass die Gesamtzahl bei 100 bleibt.
Das folgende Beispiel zeigt, wie eine Beispiel-Blogging-App eine Liste der 100 neuesten Beiträge aller Benutzer abrufen könnte:
Schnell
// Last 100 posts, these are automatically the 100 most recent // due to sorting by push() keys let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!
Ziel 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
Sie können queryStartingAtValue
, queryStartingAfterValue
, queryEndingAtValue
, queryEndingBeforeValue
und queryEqualToValue
verwenden, um beliebige Start-, End- und Äquivalenzpunkte für Abfragen auszuwä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 geordnet
In diesem Abschnitt wird erläutert, wie Daten durch die einzelnen Order-by-Methoden in der FIRDatabaseQuery
Klasse sortiert werden.
queryOrderedByKey
Wenn Sie queryOrderedByKey
zum Sortieren Ihrer Daten verwenden, werden die Daten in aufsteigender Reihenfolge nach Schlüssel zurückgegeben.
- Kinder mit einem Schlüssel, der als 32-Bit-Ganzzahl geparst werden kann, stehen an erster Stelle und werden in aufsteigender Reihenfolge sortiert.
- Als nächstes folgen Kinder mit einem Zeichenfolgenwert als Schlüssel, lexikografisch in aufsteigender Reihenfolge sortiert.
queryOrderedByValue
Bei Verwendung von queryOrderedByValue
werden untergeordnete Elemente nach ihrem Wert sortiert. Die Sortierkriterien sind dieselben wie in queryOrderedByChild
, außer 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, wie folgt sortiert:
- Kinder mit einem
nil
für den angegebenen Kinderschlüssel stehen an erster Stelle. - Als nächstes folgen Kinder mit dem Wert
false
für den angegebenen Kinderschlüssel. Wenn mehrere untergeordnete Elemente den Wertfalse
haben, werden sie lexikografisch nach Schlüssel sortiert. - Als nächstes folgen Kinder mit dem Wert
true
für den angegebenen Kinderschlüssel. Wenn mehrere untergeordnete Elemente den Werttrue
haben, werden sie lexikografisch nach Schlüssel sortiert. - Als nächstes folgen Kinder mit einem numerischen Wert, sortiert in aufsteigender Reihenfolge. Wenn mehrere untergeordnete Knoten denselben numerischen Wert für den angegebenen untergeordneten Knoten haben, werden sie nach Schlüssel sortiert.
- Zeichenfolgen kommen nach Zahlen und werden lexikografisch in aufsteigender Reihenfolge sortiert. Wenn mehrere untergeordnete Knoten denselben Wert für den angegebenen untergeordneten Knoten haben, werden sie lexikografisch nach Schlüssel sortiert.
- Die Objekte stehen an letzter Stelle und werden lexikografisch nach Schlüssel in aufsteigender Reihenfolge sortiert.
Trennen Sie Zuhörer ab
Beobachter stoppen die Datensynchronisierung nicht automatisch, wenn Sie einen ViewController
verlassen. Wenn ein Beobachter nicht ordnungsgemäß entfernt wird, synchronisiert er weiterhin Daten mit dem lokalen Speicher und behält alle beim Schließen des Ereignishandlers erfassten Objekte bei, was zu Speicherverlusten führen kann. Wenn ein Beobachter nicht mehr benötigt wird, entfernen Sie ihn, indem Sie das zugehörige FIRDatabaseHandle
an die Methode removeObserverWithHandle
übergeben.
Wenn Sie einer Referenz einen Rückrufblock hinzufügen, wird ein 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. Um die Synchronisierung von Daten an diesem Standort zu beenden, müssen Sie alle Beobachter an einem Standort entfernen, indem Sie die Methode removeAllObservers
aufrufen.
Durch den Aufruf von removeObserverWithHandle
oder removeAllObservers
für einen Listener werden die auf seinen untergeordneten Knoten registrierten Listener nicht automatisch entfernt. Sie müssen diese Verweise oder Handles auch im Auge behalten, um sie zu entfernen.