Curious how convex team architects around their userId when using Clerk
Im playing around with Next 13/14 (my app is currently in 12).
In doing so, im seeing if i can more efficiently fetch
userId
.
For context, my setup is Convex + Clerk + NextJS.
Thus far (Next 12), I've always used the userId
generated by convex from my users
table.
But given the fact that I can fetch Clerk
's userId
on the server, I'm trying to think of the pros/cons of trying to use Clerks userId instead. The main drawback is switching from the db.get(userId)
to db.query...unique()
, which I think is technically more costly even with an index applied. Then there's convex's prefetching api, where I can gain access to convex serverside. To my understanding, the primary drawback to this is that we're. losing out on convex core guarantees, but if it's just the userId we're fetching, then I assume this should be fine.
All of this to say, given that I'm venturing into a new paradigm with Next 13/14, I would love the opinions from the Convex team on how they handle this and perhaps how to think about this in general. Thank you in advance as always8 Replies
hmm ... maybe its not possible to fetch convex's userId server side
I'll let the team answer the rest, but I can at least say that a unique query on an index has been said to be equally as performant as a point query (
.get()
). And you should be able to fetch data from your tables server side, although I haven't delved into Next much to know what considerations there might be for it specifically.
Here's where the performance question was answered by Jamie: https://discord.com/channels/1019350475847499849/1019350478817079338/1177644456837652611Ah, thank you very for that. It's good to know that I dont have to consider a performance loss.
yep, 100% @erquhart is right. a .get() is an index lookup on a built-in index, so it's equivalent to a single record
eq
on your own indexDo you have an opinion on how to best architect an Next13/14 app, where the userId could either be from Clerk or Convex?
For example, with convex's prefetch api, im assuming we can fetch the
userId
server side const identity = await auth.getUserIdentity();
my advice is to avoid splitting things 50/50, which ends up being the most confusing version of everything
so that recommendation means you should immediately translate your clerk id into a convex user id
and then base everything on that convex user id
and in an ideal world, you even do that in some sort of customFunction wrapper so that you don't have to replicate this code in every mutation/query. that would be a lot of boilerplate
a good litmus test for doing this is: is your clerk identity info (
subject
or token or whatever) in more than one table? ideally it is in only one table, the users
table, and that field is indexed
then you immediately resolve any clerk id to your convex user id before you go to work on your dataIf im understanding this correctly, applying this would include adding a
clerkUserId
in the users
, which is important to immediately find the correct mapping user. From there, we use the convex's generated user._id
across the application. If so, this does seem like the simplest/most straightforward solution, and also prevents the complete dependency on Clerk should we ever decide to switch auth providers.
Im already applying this technique with the tokenIdentifier
(forgot about this)yep!