Closed noty-nick closed 2 years ago
createClient(supabaseUrl, supabaseKey, { ...otherOptions, multiTab: false })
should disable this behavior. I am not sure it's been documented (yet), but I found this option in SupabaseClientOptions
and it fixed the issue for me.
@OrangeNote thanks, I will try that
Do you mean this is expected behaviour?
I'm not sure if it's intentional or if it's an actual issue. I wonder if the object actually changes or if it's always the same after each event. If it stays the same, then I'd say it's a bug or a limitation of some sort when the multiTab
option is set.
createClient(supabaseUrl, supabaseKey, { ...otherOptions, multiTab: false })
should disable this behavior. I am not sure it's been documented (yet), but I found this option inSupabaseClientOptions
and it fixed the issue for me.
This workaround works for me, I'm closing this issue, as it looks like not a bug, but expected behaviour
It looks like that workaround has been removed.
Any guidance now that the multiTab option is no longer supported?
https://github.com/supabase/supabase-js/commit/39b2642d156caa412afaef788fdfa5a7f50e7e6f
@sjones512 I noticed that that workaround was removed too, but in the release notes for v2 I found a helpful hint.
Deprecated and removed setting for multitab support because getSession() and gotrue’s reuse interval setting takes care of session management across multiple tabs (PR)
In my case, the React user-management quickstart project, I fixed the unwanted XHR to the auth backend by making the following change in src/App.js
. I hope it helps you too!
// Before
useEffect(() => {
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session)
})
supabase.auth.onAuthStateChange((_event, session) => {
setSession(session)
})
}, [])
// After
useEffect(() => {
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session)
})
supabase.auth.onAuthStateChange((event, _session) => {
if (EVENT === 'SIGN_OUT') {
setSession(null)
}
})
}, [])
Could we reopen this? I think we need another event that is being fired when we change tabs. Because SIGNED_IN
, from my perspective, means that a user just has signed in, or got signed in, and not just the session refreshed due to changed tabs.
Maybe it would make sense to have a SIGNED_IN_REFRESH
or something, that would be fired.
I am currently handing the SIGNED_IN
so that it redirects to the home route of my app, so everytime a user changes between tabs, it'll redirect them, which is not particularly what a user would want.
Possible workaround:
let session = null;
supabase.auth.getSession().then(async ({ data }) => {
if (data.session) {
session = data.session;
}
});
supabase.auth.onAuthStateChange((event, _session) => {
if (event === 'SIGNED_IN' && !session && _session) {
// Only triggered on sign in
}
session.value = _session;
});
For SvelteKit users, I did this:
+layout.svelte
let session = null;
onMount(async () => {
// get the current session
const {
data
} = await supabaseClient.auth.getSession();
session = data.session;
// refresh: we did this when user is login with a provider (e.g google)
if (session && $page.data.session == null) {
await invalidateAll();
// location.reload();
}
// supabase auth listener
const {
data: {
subscription
}
} = supabaseClient.auth.onAuthStateChange((event, new_session) => {
/*
We did this condition cuz of this 'onAuthStateChange' function is triggered
Whenever the user changes the browser tab!
So - we do not do anything if the session is not changed!
*/
if (session?.access_token != new_session?.access_token) {
console.log('session changed');
session = new_session;
// reload all routes depends on supabase session
invalidate('supabase:auth');
if (event == 'SIGNED_IN') {
// Do what you want here
}
}
});
return () => {
subscription.unsubscribe();
};
});
For nuxt users using @nuxtjs/supabase. Seems to be working, thanks @rdunk!
<script lang="ts" setup>
import { useUsers } from "./store/user";
import { Subscription, Session } from "@supabase/gotrue-js";
let authStateSub: Subscription | null = null;
let session: Session | null = null;
onMounted(async () => {
await useSupabaseClient()
.auth.getSession()
.then(({ data }) => {
if (data.session) {
session = data.session;
}
});
authStateSub = useSupabaseClient().auth.onAuthStateChange(
async (event, _session) => {
console.log(event, session);
if (!session && _session && event === "SIGNED_IN") {
console.log("user logged in", _session.user);
await useUsers().updateOnlineStatus(_session.user.id, true);
session = _session;
} else if (session && event === "SIGNED_OUT") {
console.log("user logged out", session.user);
await useUsers().updateOnlineStatus(session.user.id, false);
session = null;
}
}
).data.subscription;
});
onUnmounted(() => {
if (authStateSub) {
authStateSub.unsubscribe();
}
});
Hi, not sure if it is related but I want to share my experience with a similar issue.
Basically, I was using the auth.onAuthStateChange
callback to make a request to the DB supabase.from('table')...
.
This resulted in a weird behaviour that was probably causing an internal loop (my guess), as any consequent query was getting stuck.
I just removed the query from the callback
For SvelteKit users, I did this:
+layout.svelte
let session = null; onMount(async () => { // get the current session const { data } = await supabaseClient.auth.getSession(); session = data.session; // refresh: we did this when user is login with a provider (e.g google) if (session && $page.data.session == null) { await invalidateAll(); // location.reload(); } // supabase auth listener const { data: { subscription } } = supabaseClient.auth.onAuthStateChange((event, new_session) => { /* We did this condition cuz of this 'onAuthStateChange' function is triggered Whenever the user changes the browser tab! So - we do not do anything if the session is not changed! */ if (session?.access_token != new_session?.access_token) { console.log('session changed'); session = new_session; // reload all routes depends on supabase session invalidate('supabase:auth'); if (event == 'SIGNED_IN') { // Do what you want here } } }); return () => { subscription.unsubscribe(); }; });
Doesn't work, if I have 2 tabs opened, if i log out on 1 tab, the other tab still can browse protected route.
Hi, not sure if it is related but I want to share my experience with a similar issue.
Basically, I was using the
auth.onAuthStateChange
callback to make a request to the DBsupabase.from('table')...
.This resulted in a weird behaviour that was probably causing an internal loop (my guess), as any consequent query was getting stuck.
I just removed the query from the callback
Thanks helped me out
Bug report
Describe the bug
auth.onAuthStateChanged triggers on tab switch
To Reproduce
Create starter project using this guide https://supabase.com/docs/guides/with-vue-3
add lines to src/main.js
run
npm run dev
open
http://localhost:3000
in browseropen dev console
Switch to another tab
Switch back to previous tab
Expected behavior
1 SIGNED_IN event in console
Actuall behaviour
2 SIGNED_IN event in console
Screenshots
https://www.loom.com/share/56993404e5f348d2bb23b68b0ad15096
System information