I have a web application utilising React and Firestore where users can create "rooms" which, when active, allow users to interact with the host. There is an option to both activate and deactivate the room to disallow interaction.
I am considering what is the best way to automatically "deactivate the room" - either when the user closes the web app (either on desktop or mobile), or if the room has been inactive for a while, something around an hour.
I have researched this and found two possibilities:
visibilityState
/ unload
, of which they seem to have their caveats on mobile, e.g.const onVisibilityChange = () => {
if (document.visibilityState === 'hidden') {
delDoc();
}
};
useLayoutEffect(() => {
document.addEventListener("unload", onVisibilityChange);
return () => document.removeEventListener("unload", onVisibilityChange);
});
For desktop: I am interested to know if the user has closed the tab or navigated away from the room hosting page.
For mobile: I am interested to know if the user has closed the tab via the browser, or if the user has force closed the browser via the app switcher.
Any help would be much appreciated.
As Pointy commented, there is no reliable way to perform an action on a client right before a web page is closed. The closest equivalent is to use the onDisconnect
feature of the Realtime Database (Firebase's other NoSQL database) to detect the client disappearing and then use Cloud Functions to bridge that information to Firestore - in the same vein as is done in Build presence in Cloud Firestore.
This is fairly non-trivial though, so a much simpler approach is to give each document a timestamp when it was last 'active' and then run a periodic Cloud Function to clean up expired documents.
And as you discovered, Firestore allows you to set a time-to-live policy on documents too, where it then auto-deleted expired documents. There is no additional cost for using the TTL service; you only pay the usual cost for deleting documents, as also shown in the documentation section on TTL pricing.