kstulgys
kstulgys•5mo ago

Is there a way to run some code just after user is created?

If yes then when and where? Is there a way to "listen" when new user or some new entry in table is created?
15 Replies
Michal Srb
Michal Srb•5mo ago
Depends on how you are creating users. Can you tell us more about your setup?
kstulgys
kstulgysOP•5mo ago
as a general question - can I somehow listen and react when row is inserted in a table? as more specific question - I'm using convex auth. When user signs in with i.e github and new user is created in users table, I want to insert some rows in some tables (this is only for new users)
Michal Srb
Michal Srb•5mo ago
general question: There are no triggers, you can call helper functions from wherever you are performing the db write. convex auth: You can customize user creation: https://labs.convex.dev/auth/advanced#controlling-user-creation-and-account-linking-behavior
Advanced: Details - Convex Auth
Authentication library for your Convex backend
kstulgys
kstulgysOP•5mo ago
I don't think I want to op-in to this 😬 When you provide this callback, the library doesn't create or update users at all. It is up to you to implement all the necessary logic for all providers you use.
Michal Srb
Michal Srb•5mo ago
Do you need account linking?
kstulgys
kstulgysOP•5mo ago
no, I need to seed some tables after user is created
Michal Srb
Michal Srb•5mo ago
I mean, if you don't need account linking at all (because you don't have 2 authentication methods that should allow the same user to log in, see the linked doc), then implementing createOrUpdateUser should be straightforward.
kstulgys
kstulgysOP•5mo ago
but as I understand I should do all the insertions in auth tables myself? ok so how can I do a row creation in another table inside that createOrUpdateUser function without messing with auth tables?
erquhart
erquhart•5mo ago
Not all auth tables, just the users table. createOrUpdateUser receives ctx as an arg, so you can insert whatever you want from that function in other tables.
async createOrUpdateUser(ctx, args) {
if (args.existingUserId) {
// Optionally merge updated fields into the existing user object here
return args.existingUserId;
}

// Implement your own account linking logic:
const existingUser = await findUserByEmail(ctx, args.profile.email);
if (existingUser) return existingUser._id;

// Implement your own user creation:
await ctx.db.insert('otherTable', { foo: 'bar' })
return ctx.db.insert("users", {
/* ... */
});
},
async createOrUpdateUser(ctx, args) {
if (args.existingUserId) {
// Optionally merge updated fields into the existing user object here
return args.existingUserId;
}

// Implement your own account linking logic:
const existingUser = await findUserByEmail(ctx, args.profile.email);
if (existingUser) return existingUser._id;

// Implement your own user creation:
await ctx.db.insert('otherTable', { foo: 'bar' })
return ctx.db.insert("users", {
/* ... */
});
},
As long as you return the id of the user you should be fine. Convex auth still handles updating all of the other auth tables, implementing this function doesn't change that.
kstulgys
kstulgysOP•5mo ago
I want to keep the initial implementation that convex/auth is using for this:
return ctx.db.insert("users", {
/* ... */
});
return ctx.db.insert("users", {
/* ... */
});
can you explain me this better? I dont understand what this do
if (args.existingUserId) {
// Optionally merge updated fields into the existing user object here
return args.existingUserId;
}
if (args.existingUserId) {
// Optionally merge updated fields into the existing user object here
return args.existingUserId;
}
erquhart
erquhart•5mo ago
That's copy pasted from the doc Michal linked earlier I'd have to look at how convex auth is getting existingUserId, but it would mean that you don't need to link anything because the existing user has already been identified. If there are other fields in the args that have changed, like eg., the user image from a GitHub login, you'll want to update that field on the users table yourself there. It is a bit rough to have to opt out of the default handling just to make changes in another table on user creation. @Michal Srb an event hook here would be really nice. I'm currently avoiding all of this by driving post user creation changes from the client, which should work fine. But it'd be nice to have it done transactionally on the backend.
Michal Srb
Michal Srb•5mo ago
I have an open PR but will discuss it more internally to see if we can improve this area altogether. Will get back to you tomorrow. https://github.com/get-convex/convex-auth/pull/48
GitHub
Callback for default user creation by xixixao · Pull Request #48 · ...
I think this is good to add for now. My hope is that we'll find the time to implement a type-safe version of the library, and in that one we wouldn't need either of these callbacks....
kstulgys
kstulgysOP•5mo ago
I'm surprised how quickly you are cooking features
erquhart
erquhart•5mo ago
I'll use for sure, thanks for this! The composable approach mentioned in the PR looks ideal too, looking forward to it.

Did you find this page helpful?