-
-
Notifications
You must be signed in to change notification settings - Fork 167
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() and user() reportedly not returning data on first invocation #23
Comments
@thorwebdev or @kiwicopple might have ideas here |
Both Do you have any more context as to why they are expecting a session to be existent? |
Thank you @awalias and Hi @thorwebdev. 1: signIn is not called initially since this goes on app load. the behavior noticed is that when called once ( or only one of them ) it still returns null while the localstorage is already filled with the session info. Hope this was clear enough, if you require more info I would be glad to answer. |
@SweeToxin I'm not able to reproduce this, can you provide a CodeSandbox that shows this behaviour? There are two scenarios here: 1. Check on page load whether a user is logged in:This works synchronously as expected. When GoTrue is initialized (which happens when the supabase client is created) the session is recovered synchronously from localstorage (https://github.com/supabase/gotrue-js/blob/master/src/GoTrueClient.ts#L57) and 2. Login from link (confirm signup / recover password / magic link)This is an asynchronous action as GoTrue needs to get the access_token from the URL and then retrieve the session from the server (https://github.com/supabase/gotrue-js/blob/master/src/GoTrueClient.ts#L187-L209). So in this scenario, So in a React application, you will want to do something like this: useEffect(() => {
setSession(supabase.auth.session()); // will return the user object for scenario 1 // null for scenario 2
setUser(supabase.auth.user()); // will return the user object for scenario 1 // null for scenario 2
// for scenario 2, this will fire a SIGNED_IN event shortly after page load once the session has been loaded from the server.
const { data: authListener } = supabase.auth.onAuthStateChange(
(event, session) => {
console.log(`Supbase auth event: ${event}`);
setSession(session);
setUser(session?.user ?? null);
}
);
return () => {
authListener.unsubscribe();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); You can find a next.js auth example here: https://github.com/supabase/supabase/tree/master/examples/nextjs-with-supabase-auth also running on CodeSandbox: https://codesandbox.io/s/github/thorwebdev/nextjs-with-supabase-auth?file=/utils/useUser.js Hope this helps. |
Hello, @thorwebdev, This sandbox should reproduce the bug. https://codesandbox.io/s/icy-star-u37g0?file=/App.svelte start it, login and reload the page, this will reproduce scenario 1. @awalias did an update on the instance I'm using and I think it solved the redirect issue, the realtime seems to be reacting to it correctly. Thank you again for your time. |
@SweeToxin thanks. I'm able to reproduce with the Svelte example. The crazy thing is, if you introduce even just a delay of 1ms it works fine: https://codesandbox.io/s/dreamy-haze-2k8rl?file=/App.svelte Does this mean svelte renders too quickly? Or is this potentially related to server-side rendering, maybe some hydration issues? @kiwicopple any ideas what we can do to fix this? @sw-yx I know you've done some stuff with Svelte. Do you maybe have an idea? |
I discovered I also needed to add a timeout in my React Native projects.
|
The issue is that when you call the supabase client constructor:
It does the following:
Because
However, in the constructor, the asynchronous method Unfortunately, by the time you've called any of the Perhaps if we made the constructor return a promise?
Then, we could do:
|
In a normal web scenario However, I guess in a RN scenario you're using AsyncStorage which might be the issue? However, for |
🎉 This issue has been resolved in version 1.9.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Okay, the following pattern should solve things across the board: https://github.com/thorwebdev/nextjs-subscription-payments/blob/main/components/UserContext.js#L13-L28 useEffect(() => {
const session = supabase.auth.session();
setSession(session);
setUser(session?.user ?? null);
const { data: authListener } = supabase.auth.onAuthStateChange(
async (event, session) => {
setSession(session);
setUser(session?.user ?? null);
}
);
return () => {
authListener.unsubscribe();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); For svelte, see an example here: https://codesandbox.io/s/optimistic-newton-4whlg?file=/App.svelte |
Nice! Thanks for the suggestion @thorwebdev! |
@thorwebdev Feel free to correct me if I am missing something, but I don't think this solves all issues. I've described in separate open ticket what the problem is: #143 (comment) If I am correct, I am not sure if we should re-open this one or just continue the work on #143 - hence, I post this here, as well. |
This uses supabase/auth-js#23 (comment) for a resolution.
As of August 2, 2022; I'm experiencing a similar issue on React Native. Due to this problem, the login screen flashes for a split second before the app redirects to an internal screen based on the current sessions that's retrieved using To remedy the issue, I tried all the recommended solutions in this thread, no luck though. In addition I tried to create a custom In any case, thanks for all the community members & maintainers for taking their valuable time to come up with solutions. TBH this is one of the best OS communities out there. FWIW, here's my AuthContext which controls all things auth in my project. If you have any suggestions as to how/why my login screen is flashing I would love to hear & try it. EditAfter fiddling with the code a little more I came up with a solution based on the information provided by @calendee. Instead of wrapping Before 👇
After 👇
|
For authState(): Observable<User | null> {
return new Observable((subscriber: Subscriber<User | null>) => {
this.supabase.auth.getSession().then(session =>
subscriber.next(session.data.session?.user)
);
const auth = this.supabase.auth.onAuthStateChange(async ({ }, session) => {
subscriber.next(session?.user);
});
return auth.data.subscription.unsubscribe;
});
} This really should be the default option for supabase-js, so that the original value is part of the observable. J |
As far as i can understand i am facing the same issue in react native. The first time the session is printed to the console, it is always null. That makes the initial route in Stack.Navigator navigate to the wrong page. I tried using timeouts as suggested above, but did not seem to work.
I grabbed that from the getting started with expo guide: https://supabase.com/docs/guides/getting-started/tutorials/with-expo Thanks for any help :) |
for me on the initial load (and sometimes not on initial load) supabase.auth.getSession, supabase.auth.refreshSession and supabase.auth.setSession just hang without ever returning anything (not even null). This makes me never wanna use Supabase again, because I have no clue how to solve this error |
I fixed the initial load error by doing this: In a react native application, do not include the detectSessionInUrl property |
The text was updated successfully, but these errors were encountered: