I’ve got a React app using socket.io and firebase auth. The socket connections are authenticated based on an authtoken set in a cookie which i get from firebase’s getIdToken method.
Normally I have this tokenRefreshingFn that refreshes the token every 25 minutes while they’re using the app because firebase id tokens (authtoken, whatever) expire every hour.
But I realized that when the user closes their laptop for awhile and comes back, when they go back to the page the authtoken will have expired since the token refreshing interval fn won’t have been executing and firebase authtokens only last 1 hour. So the socket.io server would start treating them as logged out even though they’re logged in, because the token expired while their laptop was closed.
To rectify this, i added the following useEffect to the top level of the app:
useEffect(() => {
document.addEventListener('visibilitychange', () => {
appStore.update(s => {
clearInterval(s.tokenRefreshingFn);
if (auth.currentUser) {
s.tokenRefreshingFn = setInterval(async () => {
const newAuthToken = await auth.currentUser!.getIdToken(true);
Cookies.set('authToken', newAuthToken);
}, ONE_MINUTE * 25);
} else {
s.signedIn = false;
s.tokenRefreshingFn = null;
}
});
});
}, []);
Is this valid? do you see any problems with this?
2
Answers
The Firebase SDKs take this approach to refreshing tokens and being offline:
I’d try to follow the same approach in your own code, so you may want to consider if your use-case really needs a 25 minutes interval for this.
You are using socket.io, then using connect_error is the way to go.
In your connect function, it should get the new token every time it’s called.
In most cases, the following is not necessary, since reconnection with new token is handled by your connect function.