Firebase-Anwendungen funktionieren auch dann, wenn die Netzwerkverbindung Ihrer App vorübergehend unterbrochen wird Außerdem bietet Firebase Tools zum Speichern von Daten lokal, zum Verwalten der Präsenz und zum Umgang mit Latenz.
Laufwerkspersistenz
Firebase-Apps verarbeiten vorübergehende Netzwerkunterbrechungen automatisch. Im Cache gespeicherte Daten sind offline verfügbar und Firebase sendet alle Schreibvorgänge noch einmal sobald die Netzwerkverbindung wiederhergestellt ist.
Wenn Sie die Laufwerkspersistenz aktivieren, schreibt Ihre Anwendung die Daten lokal in den damit die App auch offline den Status beibehalten kann, oder das Betriebssystem die App neu startet.
Sie können die Laufwerkspeicherung mit nur einer Codezeile aktivieren.
FirebaseDatabase.instance.setPersistenceEnabled(true);
Persistenzverhalten
Wenn Sie die Persistenz aktivieren, werden alle Daten, die der Firebase Realtime Database-Client online synchronisieren würde, auf der Festplatte gespeichert und sind auch dann offline verfügbar, wenn der Nutzer oder das Betriebssystem die App neu startet. Das bedeutet, dass Ihre App wie gewohnt funktioniert, da die im Cache gespeicherten lokalen Daten verwendet werden. Listener-Callbacks werden für lokale Updates weiterhin ausgelöst.
Der Firebase Realtime Database-Client hält automatisch eine Warteschlange aller Schreibvorgänge, die ausgeführt werden, während Ihre Anwendung offline ist. Wenn die Persistenz aktiviert ist, wird diese Warteschlange auch auf die Festplatte geschrieben, sodass alle Schreibvorgänge verfügbar sind, wenn der Nutzer oder das Betriebssystem die App neu startet. Sobald die App wieder eine Verbindung herstellen kann, werden alle Vorgänge an den Firebase Realtime Database-Server gesendet.
Wenn Ihre App Firebase Authentication verwendet, Der Firebase Realtime Database-Client hält die Authentifizierung des Nutzers bei Token bei App-Neustarts. Wenn das Authentifizierungstoken abläuft, während Ihre Anwendung offline ist, pausiert der Client bis Ihre Anwendung den Nutzer noch einmal authentifiziert. Andernfalls Schreibvorgänge können aufgrund von Sicherheitsregeln fehlschlagen.
Daten aktuell halten
Die Firebase Realtime Database synchronisiert und speichert eine lokale Kopie der Daten für aktive Zuhörer. Außerdem können Sie bestimmte Standorte synchronisiert.
final scoresRef = FirebaseDatabase.instance.ref("scores");
scoresRef.keepSynced(true);
Der Firebase Realtime Database-Client lädt die Daten automatisch unter und synchronisiert sie, auch wenn die Referenz keine aktive Zuhörer. Mit der folgenden Codezeile können Sie die Synchronisierung wieder deaktivieren.
scoresRef.keepSynced(false);
Standardmäßig werden 10 MB zuvor synchronisierter Daten im Cache gespeichert. Das sollte für die meisten Anwendungen ausreichen. Wenn der Cache die konfigurierte Größe überschreitet, Die Firebase Realtime Database löscht Daten dauerhaft, die in letzter Zeit am wenigsten verwendet wurden. Synchronisierte Daten werden nicht aus dem Cache gelöscht.
Daten offline abfragen
Die Firebase Realtime Database speichert von einer Abfrage zurückgegebene Daten zur Nutzung wenn ich offline bin. Bei Abfragen, die im Offlinemodus erstellt wurden, funktioniert die Firebase Realtime Database weiterhin für zuvor geladene Daten. Wenn die angeforderten Daten nicht geladen wurden, lädt die Firebase Realtime Database Daten aus dem lokalen Cache. Sobald die Netzwerkverbindung wiederhergestellt ist, werden die Daten geladen und die Abfrage wird berücksichtigt.
Mit diesem Code werden beispielsweise die letzten vier Elemente in einer Datenbank mit Punktzahlen abgefragt:
final scoresRef = FirebaseDatabase.instance.ref("scores");
scoresRef.orderByValue().limitToLast(4).onChildAdded.listen((event) {
debugPrint("The ${event.snapshot.key} dinosaur's score is ${event.snapshot.value}.");
});
Angenommen, die Verbindung des Nutzers bricht ab, er wechselt in den Offlinemodus und startet die App neu. Während er noch offline ist, sucht die App nach den letzten beiden Elementen am selben Ort. Durch diese Abfrage werden die letzten beiden Elemente zurückgegeben. da die App alle vier Elemente in der obigen Abfrage geladen hat.
scoresRef.orderByValue().limitToLast(2).onChildAdded.listen((event) {
debugPrint("The ${event.snapshot.key} dinosaur's score is ${event.snapshot.value}.");
});
Im vorherigen Beispiel löst der Firebase Realtime Database-Client 'Kind hinzugefügt' für die beiden Dinosaurier mit der höchsten Punktzahl. im Cache gespeichert. Es wird jedoch kein Ereignis vom Typ „value“ ausgelöst, da die App diese Abfrage nie ausgeführt hat, während sie online war.
Wenn die App die letzten sechs Elemente im Offlinemodus anfordert, erhält sie sofort Ereignisse vom Typ „untergeordnetes Element hinzugefügt“ für die vier im Cache gespeicherten Elemente. Wenn der Parameter wieder online ist, synchronisiert der Firebase Realtime Database-Client und die letzten beiden untergeordneten Elemente und die „value“ Ereignisse für die App.
Transaktionen offline abwickeln
Alle Transaktionen, die ausgeführt werden, während die App offline ist, werden in die Warteschlange gestellt. Sobald die App wieder eine Netzwerkverbindung hat, werden die Transaktionen an auf dem Realtime Database-Server.
Die Firebase Realtime Database bietet viele Funktionen für den Umgang mit Offline-Daten. Szenarien und Netzwerkkonnektivität. Der Rest dieses Leitfadens gilt für unabhängig davon, ob die Persistenz aktiviert ist.
Anwesenheit verwalten
Bei Echtzeitanwendungen ist es oft hilfreich zu erkennen, Verbindung herstellen und trennen. Zum Beispiel können Sie einen Nutzer als „offline“ markieren möchten, wenn ihr Kunde die Verbindung trennt.
Firebase Database-Clients bieten einfache Primitive, mit denen Sie in die Datenbank schreiben können, wenn ein Client die Verbindung zu den Firebase Database-Servern trennt. Diese Updates treten auf, unabhängig davon, ob der Client sauber oder nicht So können Sie sich darauf verlassen, dass die Daten auch dann bereinigt werden, wenn die Verbindung unterbrochen wird. oder ein Client abstürzt. Alle Schreibvorgänge, einschließlich Einstellung, können nach dem Trennen der Verbindung aktualisiert oder entfernt werden.
Hier ist ein einfaches Beispiel für das Schreiben von Daten nach dem Trennen der Verbindung mithilfe der Methode
onDisconnect
-Primitive:
final presenceRef = FirebaseDatabase.instance.ref("disconnectmessage");
// Write a string when this client loses connection
presenceRef.onDisconnect().set("I disconnected!");
Funktionsweise von onDisconnect
Wenn Sie einen onDisconnect()
-Vorgang einrichten, wird er auf dem Firebase Realtime Database-Server ausgeführt. Der Server prüft die Sicherheit,
stellen sicher, dass der Nutzer das angeforderte Schreibereignis ausführen kann, und informiert
wenn sie ungültig ist. Der Server überwacht dann die Verbindung. Wenn die Verbindung zu irgendeinem Zeitpunkt unterbrochen wird oder
aktiv geschlossen wird, überprüft der Server die Sicherheit
um sicherzustellen, dass der Vorgang gültig ist, und ruft dann
über den Termin.
try {
await presenceRef.onDisconnect().remove();
} catch (error) {
debugPrint("Could not establish onDisconnect event: $error");
}
Ein onDisconnect-Ereignis kann auch durch Aufrufen von .cancel()
abgebrochen werden:
final onDisconnectRef = presenceRef.onDisconnect();
onDisconnectRef.set("I disconnected");
// ...
// some time later when we change our minds
// ...
onDisconnectRef.cancel();
Verbindungsstatus erkennen
Bei vielen Präsenzfunktionen ist es hilfreich, wenn Ihre App weiß, ob sie online oder offline ist. Firebase Realtime Database bietet einen speziellen Speicherort unter /.info/connected
, der jedes Mal aktualisiert wird, wenn sich der Verbindungsstatus des Firebase Realtime Database-Clients ändert. Hier ein Beispiel:
final connectedRef = FirebaseDatabase.instance.ref(".info/connected");
connectedRef.onValue.listen((event) {
final connected = event.snapshot.value as bool? ?? false;
if (connected) {
debugPrint("Connected.");
} else {
debugPrint("Not connected.");
}
});
/.info/connected
ist ein boolescher Wert, der nicht
zwischen Realtime Database-Clients synchronisiert, da der Wert
vom Status des Clients abhängig. Mit anderen Worten: Wenn ein Kunde
Liest /.info/connected
als falsch, das ist nein
dass auch ein anderer Client
"false" liest.
Latenz verarbeiten
Server-Zeitstempel
Die Firebase Realtime Database-Server bieten einen Mechanismus zum Einfügen
Zeitstempel, die auf dem Server als Daten generiert werden. Diese Funktion in Kombination mit onDisconnect
bietet eine einfache Möglichkeit, die Zeit zu erfassen, zu der eine Verbindung zu einem Realtime Database-Client getrennt wurde:
final userLastOnlineRef =
FirebaseDatabase.instance.ref("users/joe/lastOnline");
userLastOnlineRef.onDisconnect().set(ServerValue.timestamp);
Zeitabweichung
Während ServerValue.timestamp
viel höher ist
genau und für die meisten
Lese-/Schreibvorgänge zu bevorzugen.
kann es gelegentlich nützlich sein, die Taktverzerrung des Clients
in Bezug auf die Server der Firebase Realtime Database. Ich
kann dem Standort /.info/serverTimeOffset
einen Callback hinzufügen
um den Wert in Millisekunden zu ermitteln, den Firebase Realtime Database-Clients
Zur Schätzung der lokalen gemeldeten Zeit (Epochenzeit in Millisekunden) addieren
Serverzeit. Die Genauigkeit dieses Offset kann durch die Netzwerklatenz beeinträchtigt werden. Daher ist er hauptsächlich zum Erkennen großer Abweichungen (> 1 Sekunde) bei der Uhrzeit nützlich.
final offsetRef = FirebaseDatabase.instance.ref(".info/serverTimeOffset");
offsetRef.onValue.listen((event) {
final offset = event.snapshot.value as num? ?? 0.0;
final estimatedServerTimeMs =
DateTime.now().millisecondsSinceEpoch + offset;
});
Beispiel-App für Anwesenheit
Wenn Sie die Verbindungsunterbrechungen mit der Überwachung des Verbindungsstatus und Server-Zeitstempeln kombinieren, können Sie ein System zur Nutzerpräsenz erstellen. In diesem System Jeder Nutzer speichert Daten an einem Datenbankstandort, um anzuzeigen, ob ein Realtime Database-Client ist online. Clients setzen diesen Standort auf „wahr“, wenn sie online gehen, und einen Zeitstempel, wenn die Verbindung getrennt wird. Dieser Zeitstempel gibt an, wann der betreffende Nutzer zuletzt online war.
Deine App sollte die Trennen-Vorgänge in die Warteschlange stellen, bevor ein Nutzer als online markiert wird, um Race-Bedingungen zu vermeiden, falls die Netzwerkverbindung des Clients unterbrochen wird, bevor beide Befehle an den Server gesendet werden können.
// Since I can connect from multiple devices, we store each connection
// instance separately any time that connectionsRef's value is null (i.e.
// has no children) I am offline.
final myConnectionsRef =
FirebaseDatabase.instance.ref("users/joe/connections");
// Stores the timestamp of my last disconnect (the last time I was seen online)
final lastOnlineRef =
FirebaseDatabase.instance.ref("/users/joe/lastOnline");
final connectedRef = FirebaseDatabase.instance.ref(".info/connected");
connectedRef.onValue.listen((event) {
final connected = event.snapshot.value as bool? ?? false;
if (connected) {
final con = myConnectionsRef.push();
// When this device disconnects, remove it.
con.onDisconnect().remove();
// When I disconnect, update the last time I was seen online.
lastOnlineRef.onDisconnect().set(ServerValue.timestamp);
// Add this device to my connections list.
// This value could contain info about the device or a timestamp too.
con.set(true);
}
});