Aplikacje Firebase działają nawet wtedy, gdy tymczasowo utracą połączenie sieciowe. Udostępniamy kilka narzędzi do monitorowania obecności i synchronizowania stanu lokalnego ze stanem serwera, które opisujemy w tym dokumencie.
Zarządzanie obecnością
W aplikacjach działających w czasie rzeczywistym często przydaje się możliwość wykrywania, nawiąż i rozłącz. Możesz na przykład chcesz oznaczyć użytkownika jako użytkownika offline. gdy klient się rozłącza.
Klienty bazy danych Firebase udostępniają proste elementy podstawowe umożliwiające zapisywanie w bazie danych, gdy klient odłączy się od bazy danych Firebase serwerów. Te aktualizacje pojawiają się niezależnie od tego, czy klient się rozłącza, czy nie, Możesz na nich polegać, jeśli wyczyścisz dane nawet wtedy, gdy połączenie zostanie przerwane lub po awarii klienta. Wszystkie operacje zapisu, w tym ustawienia aktualizacji i usuwania można przeprowadzić po rozłączeniu.
Oto prosty przykład zapisywania danych po odłączeniu za pomocą polecenia
Element podstawowy onDisconnect
:
Web
import { getDatabase, ref, onDisconnect } from "firebase/database"; const db = getDatabase(); const presenceRef = ref(db, "disconnectmessage"); // Write a string when this client loses connection onDisconnect(presenceRef).set("I disconnected!");
Web
var presenceRef = firebase.database().ref("disconnectmessage"); // Write a string when this client loses connection presenceRef.onDisconnect().set("I disconnected!");
Jak onOdłącz działa?
Gdy utworzysz operację onDisconnect()
,
działa na serwerze Firebase Realtime Database. Serwer sprawdza zabezpieczenia
Upewnij się, że użytkownik może wykonać żądane zdarzenie zapisu oraz informuje
aplikacji, jeśli jest ona nieprawidłowa. Serwer
oraz monitoruje połączenie. jeśli w którymkolwiek momencie połączenie zostanie przekroczone lub będzie
aktywnie zamknięte przez klienta Realtime Database, serwer sprawdza zabezpieczenia
po raz drugi (aby upewnić się, że operacja jest nadal prawidłowa), a następnie wywołuje
do zdarzenia.
Aplikacja może używać wywołania zwrotnego podczas zapisu
aby upewnić się, że łącznik onDisconnect
został prawidłowo podłączony:
Web
onDisconnect(presenceRef).remove().catch((err) => { if (err) { console.error("could not establish onDisconnect event", err); } });
Web
presenceRef.onDisconnect().remove((err) => { if (err) { console.error("could not establish onDisconnect event", err); } });
Wydarzenie onDisconnect
można też anulować, dzwoniąc pod numer .cancel()
:
Web
const onDisconnectRef = onDisconnect(presenceRef); onDisconnectRef.set("I disconnected"); // some time later when we change our minds onDisconnectRef.cancel();
Web
var onDisconnectRef = presenceRef.onDisconnect(); onDisconnectRef.set("I disconnected"); // some time later when we change our minds onDisconnectRef.cancel();
Wykrywam stan połączenia
W przypadku wielu funkcji związanych z obecnością opcja jest przydatna w aplikacji
czy jest online czy offline. Firebase Realtime Database
udostępnia specjalną lokalizację pod adresem /.info/connected
, która
jest aktualizowany za każdym razem, gdy stan połączenia klienta Firebase Realtime Database
zmian. Oto przykład:
Web
import { getDatabase, ref, onValue } from "firebase/database"; const db = getDatabase(); const connectedRef = ref(db, ".info/connected"); onValue(connectedRef, (snap) => { if (snap.val() === true) { console.log("connected"); } else { console.log("not connected"); } });
Web
var connectedRef = firebase.database().ref(".info/connected"); connectedRef.on("value", (snap) => { if (snap.val() === true) { console.log("connected"); } else { console.log("not connected"); } });
/.info/connected
jest wartością logiczną, która nie jest
zsynchronizowana między Realtime Database klientami, ponieważ wartość to
w zależności od stanu klienta. Innymi słowy, jeśli jeden klient
odczytuje /.info/connected
jako fałsz, to nie jest
zagwarantowanie, że oddzielny klient również odczyta wartość „false” (fałsz).
Czas oczekiwania na obsługę
Sygnatury czasowe serwera
Serwery Firebase Realtime Database zapewniają mechanizm wstawiania
sygnatur czasowych wygenerowanych na serwerze jako dane. Ta funkcja w połączeniu z
onDisconnect
umożliwia łatwe zanotowanie
godzina rozłączenia klienta Realtime Database:
Web
import { getDatabase, ref, onDisconnect, serverTimestamp } from "firebase/database"; const db = getDatabase(); const userLastOnlineRef = ref(db, "users/joe/lastOnline"); onDisconnect(userLastOnlineRef).set(serverTimestamp());
Web
var userLastOnlineRef = firebase.database().ref("users/joe/lastOnline"); userLastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP);
Zniekształcenie zegara
firebase.database.ServerValue.TIMESTAMP
to znacznie więcej
dokładne i zalecane w większości operacji odczytu/zapisu,
czasami może być przydatne do oszacowania zniekształcenia zegara klienta,
w odniesieniu do serwerów Firebase Realtime Database. Ty
może dołączyć oddzwonienie do lokalizacji /.info/serverTimeOffset
aby uzyskać w milisekundach wartość klientów Firebase Realtime Database
dodaj do szacunkowego czasu raportowania lokalnego (czasu epoki w milisekundach)
czas serwera. Pamiętaj, że na dokładność przesunięcia może mieć wpływ
opóźnienia sieciowe, co przydaje się przede wszystkim do wykrywania
duże (> 1 sekundę) rozbieżności w czasie zegara.
Web
import { getDatabase, ref, onValue } from "firebase/database"; const db = getDatabase(); const offsetRef = ref(db, ".info/serverTimeOffset"); onValue(offsetRef, (snap) => { const offset = snap.val(); const estimatedServerTimeMs = new Date().getTime() + offset; });
Web
var offsetRef = firebase.database().ref(".info/serverTimeOffset"); offsetRef.on("value", (snap) => { var offset = snap.val(); var estimatedServerTimeMs = new Date().getTime() + offset; });
Przykładowa aplikacja Obecność
Łącząc operacje rozłączania z monitorowaniem stanu połączenia sygnatury czasowe serwera, możesz utworzyć system wykrywania obecności użytkowników. W tym systemie każdy użytkownik przechowuje dane w lokalizacji bazy danych, aby wskazać, czy Realtime Database klient jest online. Klienci ustawili tę lokalizację na Prawda, gdy: kiedy przechodzą do trybu online, oraz podaj sygnaturę czasową po rozłączeniu. Ta sygnatura czasowa wskazuje, kiedy dany użytkownik ostatnio był online.
Pamiętaj, że aplikacja powinna zakoleć operacje rozłączania, zanim użytkownik oznaczone jako online, co pozwala uniknąć wyścigów w przypadku, gdy utracisz połączenie sieciowe, zanim możliwe będzie wysłanie obu poleceń do serwera.
Oto prosty system wykrywania obecności użytkowników:
Web
import { getDatabase, ref, onValue, push, onDisconnect, set, serverTimestamp } from "firebase/database"; // Since I can connect from multiple devices or browser tabs, we store each connection instance separately // any time that connectionsRef's value is null (i.e. has no children) I am offline const db = getDatabase(); const myConnectionsRef = ref(db, 'users/joe/connections'); // stores the timestamp of my last disconnect (the last time I was seen online) const lastOnlineRef = ref(db, 'users/joe/lastOnline'); const connectedRef = ref(db, '.info/connected'); onValue(connectedRef, (snap) => { if (snap.val() === true) { // We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect) const con = push(myConnectionsRef); // When I disconnect, remove this device onDisconnect(con).remove(); // Add this device to my connections list // this value could contain info about the device or a timestamp too set(con, true); // When I disconnect, update the last time I was seen online onDisconnect(lastOnlineRef).set(serverTimestamp()); } });
Web
// Since I can connect from multiple devices or browser tabs, we store each connection instance separately // any time that connectionsRef's value is null (i.e. has no children) I am offline var myConnectionsRef = firebase.database().ref('users/joe/connections'); // stores the timestamp of my last disconnect (the last time I was seen online) var lastOnlineRef = firebase.database().ref('users/joe/lastOnline'); var connectedRef = firebase.database().ref('.info/connected'); connectedRef.on('value', (snap) => { if (snap.val() === true) { // We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect) var con = myConnectionsRef.push(); // When I disconnect, remove this device con.onDisconnect().remove(); // Add this device to my connections list // this value could contain info about the device or a timestamp too con.set(true); // When I disconnect, update the last time I was seen online lastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP); } });