David Alonso
David Alonsoβ€’5mo ago

How to wrap the database writer so that `ctx.db.patch` and `ctx.db.insert` run side effects

Firebase has a concept of trigger functions which trigger when documents are created, updated, deleted, etc. I found this really useful since I didn't have to worry about where or how documents were updated to still be sure that a cleanup or side effect would be run. What would be a robust way to do this in Convex? I was trying to do it inside rules but quickly realized that's not possible... This is what my mental model wanted to do:
export const dbRules: Rules<AuthQueryCtx | AuthMutationCtx, DataModel> = {
fields: {
insert: async (ctx, field) => {
// TODO: Make sure we update the table views
await _backfillCollectionViewsForField(ctx, field._id);
return true;
},
},
};
export const dbRules: Rules<AuthQueryCtx | AuthMutationCtx, DataModel> = {
fields: {
insert: async (ctx, field) => {
// TODO: Make sure we update the table views
await _backfillCollectionViewsForField(ctx, field._id);
return true;
},
},
};
Problems: 1. cannot do mutations inside the handlers 2. field._id is not yet available
7 Replies
Indy
Indyβ€’5mo ago
Conceptually this is the right approach. Effectively: Wrap all writes to a table, and when the item is created, schedule a function. You can build this by effectively forking the rules wrapper and calling the relevant hook after the write vs. before. @lee is actually working on a component that does just that. Hopefully we can have that out in the not too distant future.
David Alonso
David AlonsoOPβ€’5mo ago
i see, but it's not possible to make it part of the same transaction that commits the operation on the original doc? that would already be a step up improvement over firebase's approach effectively it would be adding virtual steps to the original mutation that called e.g. ctx.db.insert but without the developer always having to remember to do that properly
lee
leeβ€’5mo ago
it's not possible to make it part of the same transaction that commits the operation on the original doc?
it is possible. the entire mutation is a transaction, including any function calls done by wrapper functions
David Alonso
David AlonsoOPβ€’5mo ago
Nice! I really can’t wait to use this so please keep me posted @lee πŸ™
lee
leeβ€’5mo ago
you can also try doing it yourself as @Indy described πŸ™‚ . We're working on the more generic solution but it may take a few weeks to release
lee
leeβ€’4mo ago
generic solution is ready πŸ˜„ https://stack.convex.dev/triggers
Database Triggers
Triggers automatically run code whenever data in a table changes. A library in the convex-helpers npm package allows you to attach trigger functions t...
jamwt
jamwtβ€’4mo ago
convex triggers are so cool. @lee has done really awesome work here

Did you find this page helpful?