Ich habe langsame Leistungsprobleme mit Firestore beim Abrufen der in einem Dokument gespeicherten Basisdaten im Vergleich zur Echtzeitdatenbank mit einem Verhältnis von 1/10.
Bei Verwendung von Firestore dauert der erste Anruf durchschnittlich 3000 ms
this.db.collection(‘testCol’)
.doc(‘testDoc’)
.valueChanges().forEach((data) => {
console.log(data);//3000 ms later
});
Bei Verwendung der Echtzeitdatenbank dauert der erste Aufruf durchschnittlich 300 ms
this.db.database.ref(‘/test’).once(‘value’).then(data => {
console.log(data); //300ms later
});
Dies ist ein Screenshot der Netzwerkkonsole:
Ich führe das Javascript SDK v4.50 mit AngularFire2 v5.0 rc.2 aus.
Hat jemand dieses Problem erlebt?
Antworten:
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()
undenableNetwork()
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?
quelle
Aktualisierungsdatum 02. März 2018
Es sieht so aus, als wäre dies ein bekanntes Problem, und die Ingenieure von Firestore arbeiten an einer Lösung. Nach einigen E-Mail-Austauschen und Code-Sharing mit einem Firestore-Techniker zu diesem Thema war dies seine heutige Antwort.
Hoffentlich wird dies bald ausgeschaltet.
Verwenden von Swift / iOS
Nach ungefähr 3 Tagen scheint das Problem definitiv get () zu sein, dh .getDocuments und .getDocument. Dinge, von denen ich dachte , dass sie die extremen, aber zeitweise auftretenden Verzögerungen verursachen, scheinen aber nicht der Fall zu sein:
Ich konnte all dies ausschließen, da ich bemerkte, dass dieses Problem nicht bei jedem Firestore-Datenbankaufruf auftrat, den ich tätigte. Nur Abfragen mit get (). Für Kicks habe ich .getDocument durch .addSnapshotListener ersetzt, um meine Daten und Voila abzurufen. Sofortiges Abrufen jedes Mal einschließlich des ersten Anrufs. Kein Kaltstart. Bisher keine Probleme mit dem .addSnapshotListener, nur getDocument (s).
Im Moment lösche ich einfach das .getDocument (), wo die Zeit entscheidend ist, und ersetze es durch .addSnapshotListener und verwende es dann
for document in querySnapshot!.documents{ // do some magical unicorn stuff here with my document.data() }
... um in Bewegung zu bleiben, bis dies von Firestore geklärt wird.
quelle
Ich hatte dieses Problem bis heute Morgen. Meine Firestore-Abfrage über iOS / Swift würde ungefähr 20 Sekunden dauern, um eine einfache, vollständig indizierte Abfrage mit nicht proportionalen Abfragezeiten für 1 zurückgegebenes Element bis zu 3.000 abzuschließen.
Meine Lösung bestand darin, die Persistenz von Offline-Daten zu deaktivieren. In meinem Fall entsprach es nicht den Anforderungen unserer Firestore-Datenbank, in der täglich große Teile der Daten aktualisiert werden.
iOS- und Android-Benutzer haben diese Option standardmäßig aktiviert, während Webbenutzer sie standardmäßig deaktiviert haben. Es lässt Firestore wahnsinnig langsam erscheinen, wenn Sie eine riesige Sammlung von Dokumenten abfragen. Grundsätzlich wird eine Kopie der Daten zwischengespeichert, die Sie abfragen (und der Sammlung, die Sie abfragen - ich glaube, es werden alle darin enthaltenen Dokumente zwischengespeichert), was zu einer hohen Speichernutzung führen kann.
In meinem Fall verursachte es eine große Wartezeit für jede Abfrage, bis das Gerät die erforderlichen Daten zwischengespeichert hatte - daher die nicht proportionalen Abfragezeiten für die zunehmende Anzahl von Elementen, die aus genau derselben Sammlung zurückgegeben wurden. Dies liegt daran, dass das Zwischenspeichern der Sammlung in jeder Abfrage dieselbe Zeit in Anspruch nahm.
Offline-Daten - aus den Cloud Firestore-Dokumenten
Ich habe ein Benchmarking durchgeführt, um diesen Effekt (mit aktivierter Offline-Persistenz) aus derselben abgefragten Sammlung anzuzeigen, jedoch mit unterschiedlichen Mengen an Elementen, die mit dem Parameter .limit zurückgegeben wurden:
Bei 100 zurückgegebenen Elementen (mit deaktivierter Offline-Persistenz) dauert meine Abfrage weniger als 1 Sekunde.
Mein Firestore-Abfragecode ist unten:
let db = Firestore.firestore() self.date = Date() let ref = db.collection("collection").whereField("Int", isEqualTo: SomeInt).order(by: "AnotherInt", descending: true).limit(to: 100) ref.getDocuments() { (querySnapshot, err) in if let err = err { print("Error getting documents: \(err)") } else { for document in querySnapshot!.documents { let data = document.data() //Do things } print("QUERY DONE") let currentTime = Date() let components = Calendar.current.dateComponents([.second], from: self.date, to: currentTime) let seconds = components.second! print("Elapsed time for Firestore query -> \(seconds)s") // Benchmark result } }
quelle
Fast 3 Jahre später ist der Firestore noch nicht in der Beta-Phase und ich kann bestätigen, dass dieses schreckliche Problem weiterhin besteht ;-(
In unserer mobilen App verwenden wir den Firebase-Client javascript / node.js. Nach vielen Tests, um herauszufinden, warum die Startzeit unserer App etwa 10 Sekunden beträgt, haben wir herausgefunden, was 70% dieser Zeit auf ... Nun, auf die Leistung von Firebase und Firestore sowie auf Kaltstartprobleme zurückzuführen ist:
Insgesamt dauert die Benutzerinitialisierung also 6 bis 7 Sekunden, was völlig inakzeptabel ist. Und wir können nichts dagegen tun. Wir können das Deaktivieren der Persistenz nicht testen, da es im Javascript-Client keine solche Option gibt. Die Persistenz ist standardmäßig immer aktiviert, sodass durch das Nichtaufrufen von enablePersistence () nichts geändert wird.
quelle
For the web, offline persistence is disabled by default. To enable persistence, call the enablePersistence method
aber ich kann bestätigen , wenn das Ganze abzurunden, unsere anfängliche Anforderung mal von einer ähnlichen ~ 8 Sekunden gehen lassen bis auf etwa ~ 500ms firebase.google.com/docs/firestore/manage-data/ enable-offlineNun, von dem, was ich derzeit mache und recherchiere, indem ich das Nexus 5X im Emulator und im echten Android-Handy Huawei P8 verwende.
Firestore und Cloud Storage bereiten mir beim ersten Dokument.get () und beim ersten storage.getDownloadUrl () Kopfschmerzen bei langsamer Reaktion.
Es gibt mir mehr als 60 Sekunden Antwort auf jede Anfrage. Die langsame Reaktion tritt nur bei echten Android-Handys auf. Nicht im Emulator. Eine andere seltsame Sache. Nach der ersten Begegnung ist die Restanforderung reibungslos.
Hier ist der einfache Code, in dem ich auf die langsame Antwort treffe.
var dbuserref = dbFireStore.collection('user').where('email','==',email); const querySnapshot = await dbuserref.get(); var url = await defaultStorage.ref(document.data().image_path).getDownloadURL();
Ich habe auch einen Link gefunden, der das gleiche erforscht. https://reformatcode.com/code/android/firestore-document-get-performance
quelle