ablobwave is there a way to perform
:ablobwave: is there a way to perform arbitrary database updates from a backend? I'm adding convex to an app that already has its own auth solution, and I'm not interested in using auth0 or openID. I just want to manage user documents manually. here's my (incomplete) code, not sure how I can get the DB here
I also don't want to make this a
mutation()
, I want it to only have this logic runnable from the backend16 Replies
hi! yeah, this is a limitation with convex right now, since queries can't modify the database.
here's some ideas for other patterns --
1. use a context at the top of your react app (similar to what you would do with an auth0 context) that queries the current user in convex (and maybe talks to your existing auth solution?) and then kicks off a mutation to initialize it if it's not present. it can then provide the user to the rest of your app through the context.
2. if the query is okay with the user not existing (since it's the one initializing it), just use
data
within the query without writing it to the database, pretending it exists. then, the first mutation called on the user can initialize it properly.
would either of those work for your use case?🤔 I guess I phrased my question weirdly. by "arbitrary updates from a backend", I mean outside of a query() or mutation() wrapper. my app is a remix (https://remix.run) app, and the code there would live inside of a regular
loader
function
ah! no problem. I'm not super familiar with remix, but the idea is that this
loader
function runs in a backend when server side rendering?correct, yeah
cool. would it work to make this logic (1) a mutation but then (2) call the mutation using our HTTP client from your remix handler? see https://docs.convex.dev/api/classes/browser.ConvexHttpClient
Class: ConvexHttpClient | Convex Developer Hub
browser.ConvexHttpClient
that way you're not using the websocket client intended for the browser
ah, yeah that should definitely work, thanks!
although, this is just a curiosity and not a major concern atm, would a client be able to, theoretically, construct an HTTP/Socket/whatever client, then call the mutation through some browser code modification?
yeah, exported queries and mutations are your app's backend's public API, and someone could create a client manually and call them directly.
convex auth can help with this, since your query or mutation can look at the context's auth (https://docs.convex.dev/generated-api/server#queryctx) and make sure the requestor is who they should be. or, in your case, maybe there'd be some token you can pass up from your auth system that you could validate in your handler to make sure it's legit?
also, we'd eventually want to make it really easy to integrate convex auth with your existing auth providers (so all of this is done automatically for you). would be curious how your auth is set up if you're comfortable sharing!
server.js | Convex Developer Hub
These exports are not directly available in the convex package!
or, in your case, maybe there'd be some token you can pass up from your auth system that you could validate in your handler to make sure it's legit?yeah, I think the easiest way here if/when I need that is some
CONVEX_ADMIN_SECRET
env variable that I can pass along
would be curious how your auth is set up if you're comfortable sharing!sure! it's handwritten cookie-based Discord oauth. user hits
/auth/discord/login
, auth with discord, discord goes back to /auth/discord/callback
which is where I upsert the user and set the cookie, then each route checks the cookie to see if the user has authorization. it's open source if you want to take a look:
https://github.com/itsMapleLeaf/charge-worlds/tree/main/app/routes/auth
https://github.com/itsMapleLeaf/charge-worlds/tree/main/app/auth
it's an awkward managerie of technologies at the moment (liveblocks, prisma, pusher 😅) and I'm hoping I can replace all of that with just convex
another related-ish question: the ConvexHttpClient doesn't appear to be typed like the rest of the library is. is that going to be updated?I tried this and I feel like I'm doing it wrong 😅

@ballingt was just working on this recently! I'm not on my dev computer now, but I think the right way to do it is to do
const client = new ConvexHttpClient<ConvexAPI>(clientConfig)
and then the subsequent method calls will be typed.that was my first guess; the class doesn't accept a generic

It will tomorrow!
I added this on Friday, @void was asking for it too
Pretty sure we can do an npm package release tomorrow, I need to fix one more thing first.
As a preview, instead of importing
ConvexAPI
from ./convex/_generated/react
it'll be called API
and imported from ./convex/_generated/api
so that you don't need React types installed.nice! thanks for that ❤️
to agree with Sujay you above now that I'm reading this, when I need a quick admin interface and I don't want to build a whole admin system with special admin users etc. I write mutations that require a secret key so they can't be called by anyone else
and sometimes editing fields in the dashboard is enough!
actually just hit another issue, but I'll start a new message since it's unrelated