-
-
Notifications
You must be signed in to change notification settings - Fork 23
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
Realtime #76
Comments
There might be a better way to do this, so I wanted to hold off on an MR. But fundamentally, this is what is needed to get realtime + RLS working. |
Hello, yes you are right. Support for realtime in this repo has been removed (it is on a branch, outdated: https://github.com/rphlmr/supa-fly-stack/blob/feat/add-supabase-client-provider/app/integrations/supabase/provider.tsx). I have plans to make improvements but time is missing to work on it right now 🫣 On production, I use an other strategy with a Context provider giving access to accessToken: //provider
const AuthContext = createContext<{
accessToken: string | undefined;
}>({ accessToken: undefined });
// in root.tsx, wrap <Outlet /> with <AuthProvider authSession={authSession}> to use access token in supabase'browser client
export const AuthProvider = ({
children,
authSession,
}: {
children: ReactElement;
authSession: Partial<AuthSession>;
}) => {
// what root loader data returns
const { accessToken, expiresIn } = authSession;
const refresh = useFetcher();
// trigger a refresh session at expire time. We'll send a post request to our resource route /refresh-session
useInterval(() => {
// ask to refresh only if expiresIn is defined
// prevents trying to refresh when user is not logged in
if (expiresIn)
refresh.submit(null, {
method: "post",
action: "/refresh-session",
encType: "application/x-www-form-urlencoded",
});
}, expiresIn);
const value = useMemo(() => ({ accessToken }), [accessToken]);
return (
<AuthContext.Provider value={value}>{children}</AuthContext.Provider>
);
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (isBrowser && context === undefined) {
throw new Error(`useAuth must be used within a AuthProvider.`);
}
return context;
}; //route: refresh-session
export async function action({ request }: ActionArgs) {
const authSession = await refreshAuthSession(request);
return response.ok(
{ success: true },
{
authSession,
}
);
} // in root.tsx
// authSession comes from root loader function
<AuthProvider authSession={authSession}>
<Outlet />
</AuthProvider> //usage
function useWatchLiveEvents() {
const { accessToken } = useAuth();
const revalidate = useRevalidator().revalidate;
useEffect(() => {
if (!accessToken) return;
supabaseClient.realtime.setAuth(accessToken);
const channel = supabaseClient
.channel(`db-changes`)
.on(
"postgres_changes",
{
event: "DELETE",
schema: "public",
table: "transaction",
},
() => {
revalidate();
}
)
.subscribe();
return () => {
supabaseClient.removeChannel(channel);
};
}, [accessToken, revalidate]);
} |
Ahh that's nice! Thanks for the tip. Closing this. |
I was having trouble getting realtime to work with RLS. I was able to get it working like this:
Without this, the realtime claims in the
realtime.subscriptions
table were equivalent to a user with"role":"anon"
The text was updated successfully, but these errors were encountered: