next-auth: getSession call does not trigger session object update until window loses focus
I’m currently trying to update some page components when the session changes after an onClick-triggered Promise is fulfilled. Here the function DeleteGroup returns a Promise. I print the value of the session before the Promise is returned, and then print it again after it is fulfilled by calling getSession().
<Button
onClick={() => {
console.log(session);
DeleteGroup(value.id).then(async () => console.log(await getSession()));
}}
>
According to the console, everything I’ve logged looks right. The initial console.log(session) output shows groups as an Array of length 2, while the second console.log(await getSession()) output shows it as length 1.
However, until the window loses focus, my UI continues to show 2 groups despite the console output clearly showing the result of the getSession call having only 1 group. My UI is immediately synced once the window loses focus, so I do not believe there is anything wrong with the way I’ve written my UI components. If that is the case, why wouldn’t my getSession() call immediately update the UI accordingly?
Apologies if this is a repeat; I find session updating to be the trickiest part of Next-Auth.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 28
- Comments: 36 (8 by maintainers)
Commits related to this issue
- 💩 refresh page to refresh session https://github.com/nextauthjs/next-auth/discussions/3941 https://github.com/nextauthjs/next-auth/issues/596 — committed to AliProximo/aliproximo by thlmenezes 2 years ago
One way to trigger the internal session re-validation on the active(!) window (thx to @ValentinH for providing some insights) might be to manually trigger a
visibilitychangeeventhttps://github.com/nextauthjs/next-auth/blob/main/src/client/index.js#L72
this seems to be a working hack for me that does not require a full page reload or
signIn@ValentinH @blms Thanks to you both!
This is helpful and I think we understand it well enough to fix now.
It’s supposed to work as described in the docs, but I think is inadvertently relying on localStorage to trigger the event and the way localStorage events work is they only trigger updates in windows other than the window that triggered the event.
+1. NextAuth gets me to the 99 yard line and then fumbles the ball by not being able to trigger a session state update from within the client (w/o needing to resort to fragile hackery). Calling getSession exhibits all the right behaviors throughout the stack except for updating state :0( Frankly, I’m surprised to see how old this issue is (and others like it) w/o any resolution for such an essential capability. NextAuth is an overall excellent, well-maintained library IMHO, and super appreciate the contrib, but I may need to bail on it over this issue given the inaction.
I want to give this issue a bump and see if we can move this along. Not being able to refresh sessions and have updates propagate is a big problem for us.
Unfortunately the solutions provide either don’t seem to work or require reloading the page which is a non-starter for long-running real-time WebSocket based applications.(I spoke too soon. This does seem to work https://github.com/nextauthjs/next-auth/issues/596#issuecomment-943453568 but it is a very ugly hack). It seems that session refreshing is one of, if not the most frequent pain points for using NextAuth, as everyone is converging on these same questions in a number of places.The work that’s been done on NextAuth provides a ton of value and I really appreciate it. Unfortunately, not having token refresh is a pretty critical flaw that makes the rest of the library not particularly useful in all but the simplest of cases. It looks like https://github.com/nextauthjs/next-auth/pull/4744 has been open for some time. Could I kindly ask that it’s either merged or it’s made clear why it can’t be merged so that we can work on an updated solution?
Ok, it works.
Doing as @PhilippLgh said :
event triggering :
just works ! it does refresh the session.
@balazsorban44 Could this be a way ?
Nope, sorry, I gave up and dropped NextAuth.
Any solutions/workarounds for latest versions? 😃
Any news on the issue? following @timshingyu I’m also doing it via
useSwrnow:In case someone looking for a workaround. I just replace useSession hook and use
useSWRlibrary instead.I just noticed the same issue: if I call
getSession()to trigger a session update, the call is correctly sent by the context is not updated. I think I understand why but I’m not sure how to fix it.The first thing would be that we need to pass
{triggerEvent: true}togetSession()so that it updates the localStorage to inform other windows: this line.However, the code responsible to update the session following such a message has an explicit check to not update the session if the window is coming from the same window: this line
The problem is that the only way to update the Context is to call the internal
_getSessionof the_useSessionHook()via__NEXTAUTH._getSession().I think this part of the doc is misleading:
It’s actually “you can can trigger an update of the session object across all other tabs/windows”.
Are we trying to do something that is not intended or is there a way to imperatively trigger a session update that would update the context of the current window?
The new implementation uses a BroadcastChannel based on the localStorage API. This could work (not tested):
Alternatively use
getSession({ broadcast: true })This hack stopped working in NextAuth@4. Not 100% sure why, but haven’t been able to get an alternative hack working yet. Anyone have a workaround yet for this in v4?
Seems to work for me. Here’s my set up.
Here’s how I’m using it.
@zanami did you find the right solution for this? I’m in the same situation as you…
Heads up, my earlier suggestion still works (
"next-auth": "^4.19.1").Such an old and important issue, and no progress at all? 😦
The solution with
new Event('visibilitychange')works only when the flagrefetchOnWindowFocusis set totrueonSessionProvider.In case we don’t want to auto-update the session when a user switches windows we’re kind of stuck.
@PhilippLgh Looks like it’s also possible to use the exported
BroadcastChannelfunction directly.Unfortunately, it doesn’t really trigger XHR to update the session.
Even if we add
await getSession()it seems theSessionProviderdoesn’t propagate the changes on the client.It’s possible that PR #4744 fixes it, but it’s still pending review.
Call database many time not really good, btw I use JWT too 😦
Only solution so fat is to call your db and update the session yourself in the session callback…
I think triggering a re-signin is the easiest method here. this will invoke the jwt callback with the new data, and a second login on most OAuth providers is barely visible as it will be a fast redirect (unless some params explicitly require the user to give their credentials again)