UPDATE: 12. Februar 2018 - iOS Firestore SDK v0.10.0
Ähnlich wie bei einigen anderen Kommentatoren habe ich auch bei der ersten Abrufanforderung eine langsamere Antwort festgestellt (wobei nachfolgende Anforderungen ~ 100 ms dauern). Für mich ist es nicht so schlimm wie 30s, aber vielleicht 2-3 Sekunden, wenn ich eine gute Konnektivität habe, was ausreicht, um beim Starten meiner App eine schlechte Benutzererfahrung zu bieten.
Firebase hat mitgeteilt, dass sie sich dieses "Kaltstart" -Problems bewusst sind und an einer langfristigen Lösung dafür arbeiten - leider keine ETA. Ich denke, es ist ein separates Problem, dass es bei schlechter Konnektivität Ewigkeiten (über 30 Sekunden) dauern kann, bis sich Anfragen zum Lesen aus dem Cache entscheiden.
Während Firebase all diese Probleme behebt, habe ich begonnen, die neuen disableNetwork()
und enableNetwork()
Methoden (verfügbar in Firestore v0.10.0) zu verwenden, um den Online- / Offline-Status von Firebase manuell zu steuern. Obwohl ich sehr vorsichtig sein musste, wo ich es in meinem Code verwende, da es einen Firestore-Fehler gibt, der unter bestimmten Umständen einen Absturz verursachen kann.
UPDATE: 15. November 2017 - iOS Firestore SDK v0.9.2
Es scheint, dass das Problem mit der langsamen Leistung jetzt behoben wurde. Ich habe die unten beschriebenen Tests erneut ausgeführt, und die Zeit, die Firestore benötigt, um die 100 Dokumente zurückzugeben, scheint nun konstant bei 100 ms zu liegen.
Ich bin mir nicht sicher, ob dies ein Fix im neuesten SDK v0.9.2 war oder ob es ein Backend-Fix (oder beides) war, aber ich schlage vor, dass jeder seine Firebase-Pods aktualisiert. Meine App reagiert deutlich schneller - ähnlich wie in der Echtzeit-Datenbank.
Ich habe auch festgestellt, dass Firestore viel langsamer als Realtime DB ist, insbesondere beim Lesen aus vielen Dokumenten.
Aktualisierte Tests (mit dem neuesten iOS Firestore SDK v0.9.0):
Ich habe ein Testprojekt in iOS Swift mit RTDB und Firestore eingerichtet und jeweils 100 sequentielle Lesevorgänge ausgeführt. Für die RTDB habe ich das ObservSingleEvent getestet und Methoden auf jedem der 100 Knoten der obersten Ebene beobachtet. Für Firestore habe ich die Methoden getDocument und addSnapshotListener für jedes der 100 Dokumente in der TestCol-Auflistung verwendet. Ich habe die Tests mit ein- und ausgeschalteter Festplattenpersistenz ausgeführt. Bitte beachten Sie das beigefügte Bild, das die Datenstruktur für jede Datenbank zeigt.
Ich habe den Test 10 Mal für jede Datenbank auf demselben Gerät und einem stabilen WLAN-Netzwerk ausgeführt. Bestehende Beobachter und Zuhörer wurden vor jedem neuen Lauf zerstört.
Echtzeit-DB-ObservSingleEvent-Methode:
func rtdbObserveSingle() {
let start = UInt64(floor(Date().timeIntervalSince1970 * 1000))
print("Started reading from RTDB at: \(start)")
for i in 1...100 {
Database.database().reference().child(String(i)).observeSingleEvent(of: .value) { snapshot in
let time = UInt64(floor(Date().timeIntervalSince1970 * 1000))
let data = snapshot.value as? [String: String] ?? [:]
print("Data: \(data). Returned at: \(time)")
}
}
}
Echtzeit-DB-Beobachtungsmethode:
func rtdbObserve() {
let start = UInt64(floor(Date().timeIntervalSince1970 * 1000))
print("Started reading from RTDB at: \(start)")
for i in 1...100 {
Database.database().reference().child(String(i)).observe(.value) { snapshot in
let time = UInt64(floor(Date().timeIntervalSince1970 * 1000))
let data = snapshot.value as? [String: String] ?? [:]
print("Data: \(data). Returned at: \(time)")
}
}
}
Firestore getDocument-Methode:
func fsGetDocument() {
let start = UInt64(floor(Date().timeIntervalSince1970 * 1000))
print("Started reading from FS at: \(start)")
for i in 1...100 {
Firestore.firestore().collection("TestCol").document(String(i)).getDocument() { document, error in
let time = UInt64(floor(Date().timeIntervalSince1970 * 1000))
guard let document = document, document.exists && error == nil else {
print("Error: \(error?.localizedDescription ?? "nil"). Returned at: \(time)")
return
}
let data = document.data() as? [String: String] ?? [:]
print("Data: \(data). Returned at: \(time)")
}
}
}
Firestore addSnapshotListener-Methode:
func fsAddSnapshotListener() {
let start = UInt64(floor(Date().timeIntervalSince1970 * 1000))
print("Started reading from FS at: \(start)")
for i in 1...100 {
Firestore.firestore().collection("TestCol").document(String(i)).addSnapshotListener() { document, error in
let time = UInt64(floor(Date().timeIntervalSince1970 * 1000))
guard let document = document, document.exists && error == nil else {
print("Error: \(error?.localizedDescription ?? "nil"). Returned at: \(time)")
return
}
let data = document.data() as? [String: String] ?? [:]
print("Data: \(data). Returned at: \(time)")
}
}
}
Jede Methode druckt den Unix-Zeitstempel im Wesentlichen in Millisekunden, wenn die Methode ausgeführt wird, und druckt dann einen weiteren Unix-Zeitstempel, wenn jede Leseoperation zurückkehrt. Ich habe die Differenz zwischen dem anfänglichen Zeitstempel und dem letzten zurückgegebenen Zeitstempel genommen.
ERGEBNISSE - Festplattenpersistenz deaktiviert:
ERGEBNISSE - Festplattenpersistenz aktiviert:
Datenstruktur:
Wenn die Methoden getDocument / addSnapshotListener von Firestore nicht mehr funktionieren, scheint sie für eine Dauer von ungefähr einem Vielfachen von 30 Sekunden hängen zu bleiben. Vielleicht könnte dies dem Firebase-Team helfen, herauszufinden, wo im SDK es stecken bleibt?