auth-js
auth-js copied to clipboard
Auth state change events not firing on web page load
Bug report
Describe the bug
When loading a web page with a supabase onAuthStateChange
handler, one would expect the signed in event to fire once the page loads and the connection is established. But due to some recent code changes around how session restore is handled, this basically prevents any event handler from being registered. The SIGNED_IN
event notification is fired as part of the Supabase client constructor.
To Reproduce
Steps to reproduce the behavior:
- Have an onAuthStateChanged handler.
- Load your script on a web page.
Expected behavior
The event handler fires.
Additional context
The problem is very apparent in a multi-page application/"regular website" with a Supabase connection. I think the issue is especially tied to this commit: https://github.com/supabase/gotrue-js/commit/3a670be41d6fa3d9c3022730f662b2ff03b57469
I was using 1.7.x before, and the event would fire when the web page loads.
Maybe some kind of event handler buffer could be introduced? Buffer auth events until a handler is added, then fire them all immediately.
Hey @ProjectMoon - you're right - we had to re-eng this so that it would return from the constructor instead.
The problem is very apparent in a multi-page application/"regular website" with a Supabase connection
Can you clarify more about the problem? Not you should be able to inspect supabase.auth.session()
immediately (like this), and this will return a logged-in session (if there is a valid session)
The session exists and the user is logged in, yes. I have a very simple website where a user can log in to get a bit more information. Originally on Firebase, and before the recent changes, I relied on the auth state change event to fire so I could fetch and display the information/links/etc for logged in users. With this change, the event never fires and thus the page does not get updated for logged in users.
Is there a workaround maybe?
With this change, the event never fires and thus the page does not get updated for logged in users
because session recovering now happens on constructor which is before any onAuthStateChange subscription.
For your use case, You can check for current session along with onAuthStateChange
supabase.auth.onAuthStateChange((event, session) => {
// on event == SIGNED_IN, do s.th
})
if (supabase.auth.session()) {
// user login, do s.th
}
Here's the workaround function I have made for now:
type AuthChangeHandler = (event: supabase.AuthChangeEvent, session: supabase.Session | null) => void;
export function onAuthStateChange(client: supabase.SupabaseClient, callback: AuthChangeHandler) {
document.addEventListener('DOMContentLoaded', function() {
if (client.auth.session()) {
callback('SIGNED_IN', client.auth.session());
}
});
client.auth.onAuthStateChange((event, session) => {
callback(event, session);
});
}
One year later is this workaround still necessary?
I'm trying to use Supabase again after about a year of absence and I found that following the examples given by the docs sometimes the events don't get fired especially when trying to use a third-party OAuth provider like GitHub.
The user is redirected back to my sign in page with an access token in the URL but then nothing happens. I expect the event to be fired and the user to get redirected to the dashboard on server side, but that's not the case.
Hi @milovangudelj, it would be great if you can elaborate more on this point:
I expect the event to be fired and the user to get redirected to the dashboard on server side
The event only gets fire after the user is redirected to the dashboard. This is because we can only confirm that the user is signed in if the oauth callback is successful.
If the oauth callback is successful and the user is redirected to the dashboard, there should be a "SIGNED_IN" event fired which you can listen to using onAuthStateChange
. Will be closing this issue for now but feel free to reopen if you wish to clarify and elaborate on your usecase.