Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session doesn't seem to update until a whole server-side page reload happens #1667

Closed
1 of 5 tasks
jhackett1 opened this issue Apr 7, 2021 · 5 comments
Closed
1 of 5 tasks
Labels
bug Something isn't working

Comments

@jhackett1
Copy link
Contributor

jhackett1 commented Apr 7, 2021

Describe the bug

I'm using the useSession hook to grab some information about the logged in user, which I've customised using a callback:

callbacks: {
    // include extra info in the session object
    async session(session, user) {
        session.user.id = user.id
        session.user.signature = user.signature
        return session
    },
}

I have a "user profile" form which, when submitted, updates the currently logged in user in the database (specifically the signature column above, which stores a short string). i can verify that the changes have been made to the database right away.

However, the session seems to still be returning the data before the change.

I need to make a full page reload from the server to bring it into sync with the database.

This is only a small change so I don't think there's a security risk, but what might happen if the things the user was allowed to access changed? Would the session not catch up until a full page reload?

Steps to reproduce

https://github.com/jhackett1/sms-message-tool

see:

Expected behavior

The useSession hook should always return correct, up to date information about the user

From the docs:

The session state is automatically synchronized across all open tabs/windows and they are all updated whenever they gain or lose focus or the state changes in any of them (e.g. a user signs in or out).

Screenshots or error logs

console.log(session) on the same page as the form returns the out-of-date data, so I can rule out my form being the source of the problem.

I see no other errors or log messages that might help.

Additional context

    "next": "^10.0.9",
    "next-auth": "^3.13.2",

Feedback

Documentation refers to searching through online documentation, code comments and issue history. The example project refers to next-auth-example.

  • Found the documentation helpful
  • Found documentation but was incomplete
  • Could not find relevant documentation
  • Found the example project helpful
  • Did not find the example project helpful
@jhackett1 jhackett1 added the bug Something isn't working label Apr 7, 2021
@balazsorban44
Copy link
Member

balazsorban44 commented Apr 7, 2021

The docs also says (right under what you quoted)

If you have session expiry times of 30 days (the default) or more then you probably don't need to change any of the default options in the Provider. If you need to, you can can trigger an update of the session object across all tabs/windows by calling getSession() from a client side function.

Didn't that help? So after you updated the session, just call getSession() as well.

@jhackett1
Copy link
Contributor Author

hmmm, doesn't seem to have made a difference. - i've added await getSession() as the very last thing the form submit handler does, after awaiting a successful response from the api, but i see no difference to the behaviour i described above

@jhackett1
Copy link
Contributor Author

but...explicitly doing something like this does seem to solve the problem:

  const [session, setSession] = useState(false)

  useEffect(async () => {
    setSession(await getSession())
  }, [])

why are these two behaviours different? i did assume that this code is broadly what useSession looked like under the hood

@balazsorban44
Copy link
Member

balazsorban44 commented Apr 7, 2021

Hmm. I think it should at least be:

const [session, setSession] = useState(false)
useEffect(() => {
  (async() => {
    setSession(await getSession())
  })()
}, [])

I don't think useEffect can/should take an async callback. (If you have ESLint set up with React, it should probably warn you about this)

The current implementation of useSession is certainly not ideal at the moment to be honest, I am trying to address it in #1473, to make it play nicer with React, but should work as-is.

I also haven't tried updating the session before, so I only quoted our documentation.

Looking at the implementation of getSession:

export async function getSession (ctx) {
const session = await _fetchData('session', ctx)
if (ctx?.triggerEvent ?? true) {
broadcast.post({ event: 'session', data: { trigger: 'getSession' } })
}
return session
}

My feeling was that when calling getSession(), it should broadcast to all open windows to re-fetch the session, but looking at the implementation closer, there might be some issue with this.

Could you verify that if you have two tabs (opened from the same window) open, and updating session from one of the tabs will update the session in the other tab when you call getSession() you first tried?

You should probably also await at this line, before you call getSession: https://github.com/jhackett1/sms-message-tool/blob/5bbfb5cd2f177f1ddba8c441b06aee4327367705/pages/settings.jsx#L32, if possible. not familiar with swr mutate.

@balazsorban44
Copy link
Member

balazsorban44 commented Apr 7, 2021

Actually, I found an existing issue about this: #596

Duplicate of #596, I will close this for now, but feel free to continue the discussion there!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants