when is the best time to create a user entry in the db?
hi all!
im curious what's the best practice here. assume that i have a to-do list app and using clerk for auth. if i allow the user to sign in via google, there's no clear way to do "user has signed up" -> "i need to register user in db."
when should i create an entry of the user in the db? im thinking of when the user has created a to-do list and clicked on the save button, i can check if the user has existed in the
when should i create an entry of the user in the db? im thinking of when the user has created a to-do list and clicked on the save button, i can check if the user has existed in the
users
db and create the entry.
is this reasonable? thank you18 Replies
That seems reasonable. I feel like this is not a Convex-specific question: You'll have to consider your own circumstances. Clerk charges per active user, so you'll need to consider your revenue per Clerk user.
For a to-do app, you may want to delay creating a user account in Clerk for as long as possible:
- Perhaps add your settings page to your publicRoutes in middleware.ts.
- Enable anonymous accounts if possible. I don't think this is a native feature of Clerk, though. I am thinking something like this: https://firebase.google.com/docs/auth/web/anonymous-auth
So, I think you would need to use the <Authenticated>, <Unauthenticated>, <AuthLoading> components a lot
In this Discord server, some Convex staff have made some informal comments about building a native lightweight auth.
It's not clear to me whether a native auth solution would be net-positive to Convex Inc.. But it would be interesting if developers had a way to very affordably create user accounts, but have
- those user accounts work alongside full-blown Clerk accounts.
- a path to converting them to Clerk user accounts
ooof good point... damn i should write a cron to kick users who are inactive for 30 days 😛
Clerk only charges per active user
awesome! i guess that's fine then. what are you u using for ur auth? is it clerk too?
I am using Clerk
But i have experience with Okta, Firebase, and Appian auth
This blog post is from Feb 2023, but still relevant: https://blog.hyperknot.com/p/comparing-auth-providers
I think with a B2C product with low revenue per user, you will run into this issue with any auth vendor
I think part of why Supabase got famous is their affordable auth. This blog says "Supabase Auth is the gateway drug to the platform."
But the Supabase CEO in interviews says the auth team is "always busy"
And auth is a easy way for disgruntled people on the internet to criticize the platform in a low-effort way
I think Clerk is the optimal path for now, all things considered
If you are building a to-do app for your own learning purposes and not as a business, then you should definitely use Clerk. Clerk will teach you what good looks like and slowly introduce you to OAuth concepts over time
earlier in my career, mid-2010's, I manually built OAuth integrations for LinkedIn and Facebook. Made a claim for a token and stored it in my own database. It was hard. I had to learn each sub-concept from fresh. Very tedious
This has come up a few times and I haven't seen a canonical approach. I use Clerk, and run an upsert every time a user authenticates. I also update user info from Clerk in the same function, rather than using Clerk's webhooks (for now).
@erquhart - So are you saying that every time you execute an upsert on a table with a foreign key to
users
, you are running updateUser()?No, every time a user authenticates to my app, I call
updateUser()
, which runs an upsert underneath, inserting the new user or updating the user's data (if there's a delta between their clerk info and the info in the convex db).
(Or maybe "yes" if we're saying the same thing? 😄)I think I understand. You are executing the updateUser() every time the user makes a sign-in.
It's lazy lol, but it works
(It also covers initial sign up without any special logic)
thank you erquhart sir. sounds like this is the best way to do it
yea i agree. but i dont wanna spend time doing auth. and clerk is easy to setup 😅
Yeah, at least for getting going. Go back and firm up once the thing makes some money lol
I forgot: clerk has first day free pricing
First Day Free means no charges for users who sign-up but never return. Users are only counted as active when they come back after 24 hours.
So, no strong need to put a lot of effort into delaying the user account creation
I think im definitely day 1 creating user. Just thinking whats the best way to register them in my convex users table, 😅
Relevant docs: https://docs.convex.dev/auth/database-auth
Better documentation for webhooks will be released next week.
Storing Users in the Convex Database | Convex Developer Hub
You might want to store user information directly in your Convex database, for
Oh is this what i needed! Thank you!!
quick follow up: what's the best way to send an email to the user who just signed up? since sending an email using resend requires me to use an action and
createUser
is a mutation, does it mean i need to use an action to "wrap" the createUser
mutation and sendEmail
action?Sounds like you want to schedule the action to send an email from the mutation that creates the user (e.g.
ctx.scheduler.runAfter(0, internal.users.sendEmail, ...)
)
These docs (https://docs.convex.dev/functions/actions#calling-actions-from-clients, https://docs.convex.dev/zen) touch on this, but wrapping the whole thing in an action (vs. scheduling) is generally an anti-pattern since it means you lose out on a lot of the benefits of a mutation (e.g. they're guaranteed to run exactly once)Actions | Convex Developer Hub
Actions can call third party services to do things such as processing a payment
ahhh thank you. totally forgot bout the scheduler 🤦♂️