`<Unauthenticated>` renders after sign in redirect
I'm using Clerk's
<SignIn />
and <SignUp />
components on their own dedicated routes (using Remix)—/sign-in
and /sign-up
respectively. When a user navigates to the index route /
, I use the <Unauthenticated />
component to conditionally render Clerks' <RedirectToSignIn />
component, which does what it sounds like. This all works great without issue, until the user signs in—once that happens, the user is redirected back to /
, and then—apparently because there is some delay between this redirect and the <Unauthenticated />
component registering that the user is now authenticated—the <Unauthenticated />
component redirects the user to the the sign in route, which then redirects the user to the index route (because Clerk realizes they're already logged in), which then redirects the user to the sign in route, etc.
I was able to break this loop by replacing
with
But of course that's not ideal!7 Replies
Hey RJ I’d have to play with this a bit to be sure how to approach it but one thing you could give a try is to do this without the convex helper components. If that’s working you can put a convex helper component inside the clerk one.
Wrapping the Convex auth status in the Clerk auth status worked! But it's a bit tricky to get right (especially while making sure the loading state isn't re-rendered needlessly). Here's the code I used:
(free labor community contribution, I would be happy to look into updating that now that y'all have open-sourced the Convex JS library.
match
is pattern-matching via ts-pattern
[https://github.com/gvergnaud/ts-pattern#about])
Part of what makes the above code so tricky is that both Convex and Clerk have overly-complex return signatures. To use Convex as an example, there are really only three possible states (as reflected in the exposed helper components) that Convex auth can be in:
But instead of returning a sum type, useConvexAuth
returns instead a product type, which has four possible values:
The four possible types are { true, true }
, { true, false }
, { false, true }
and { false, false }
—or the number of possible values for each field (2 each, because they're each booleans) times the number of fields (2), 2 * 2 = 4
(hence the term "product type").
The one value which is nonsensical is:
So as an aside, it would be nice to fix in useConvexAuth
!
If you want some Hey @RJ rereading all of this I think using
should actually work. Are you on latest version of Convex? There is one more fix in 0.14.1-alpha.0 but that should not be impacting you here (although you could try it out to see).
I'm not, but I'm upgrading now, so I'll try it again once I'm finished with the upgrade.
I've upgraded to
0.14.1
and this bug is still present @Michal Srb
Actually, I only verified that it's present using useConvexAuth
, let me verify that it's also present with the <Unauthenticated />
component
Yeah, same behavior with the componentsI have the same, or a similar problem.
In the app I am working on we create a ghost user in the browser if the user is not authenticated (that will later be merged with the actual user when the user sign in or sign up).
To do this, I need to know if the user is loading (undefined), anonymous (null), or authenticated (User).
My getUser query uses
const identity = await auth.getUserIdentity();
which only returns the user or null. So I can't know if it is loading or if there is no user.
Eg on the client, the loading states are:
Anonymous
1. undefined (loading)
2. null
Authenticated
1. undefined (loading)
2. null <------ This should not happen
3. User
Okay, I guess I can solve this with Clerk useUser() or useConvexAuth().
But oh man, so many options:
const { user: clerkViewer } = useUser();
const convexViewer = useQuery("getViewer");
const convexAuth = useConvexAuth();
🙃Hey @Mikael Lirbank ,
useConvexAuth
should be the authoritative source of truth for whether the client has loaded up the auth provider library and the information was passed to your Convex backend. If useConvexAuth
returns isAuthenticated: true
and your function's getUserIdentity
returns null you should be guaranteed that the user is not currently logged in.
@RJ any chance you could boil down the bug to a minimal repro codebase and push it to a github repo? I was not able to reproduce the issue.Yes, happy to give it a shot!
Sorry to have you attempt repro without success here 😕