Auth with chained actions and mutations?
I'm using a mutation that schedules an action. This action runs a bunch of actions one after the other. The first action runs a public mutation which has an authentication guard (a functiont that throws if the user is not auth). This function is throwing an error even if the user is logged in
7 Replies
This is an example of pseudocode:
(continue)
I find if I simply call the
processRaw
action from the client, everything works. Is it that when using the scheduler, the user auth is lost somehow?@saito200 hey! yeah, the auth is tied to the session cookie. if you want to perist the identity in a scheduled function, you can just toss the
UserIdentity
object into the argument list to your scheduled function https://docs.convex.dev/api/interfaces/server.UserIdentityInterface: UserIdentity | Convex Developer Hub
server.UserIdentity
Is there a reason for not authenticating before scheduling the first action?
@ian reusability. For example if I am reusing a query that gets the current user to filter records by user id
Gotcha. Yeah once you're out of the user request flow (e.g. in a scheduled function) you no longer have access to the user request metadata, like the logged in user. This is in part b/c if your auth credentials expire, the client could re-authenticate and retry transparently, but a scheduled function would just fail. In these cases I would recommend having an argument of the userId and having it be an internalQuery / internalMutation that is only called by trusted code.
I am finding it much simpler if I just do not use the scheduler at all and run actions directly from the client tbh, and only go out of the way to use the scheduler if I expect lots of reads and writes
I can see that. Note that actions won't get automatically retried the way mutations will, since we don't know if they're idempotent. So if your client -> server network flakes, it'll be up to you to decide if/when to do retries, and how to evaluate if the action started even if the network didn't get the result. This is one reason we suggest folks do the write -> schedule -> write back flow - you can know the state at each step. But just a suggestion. I also have had times where it's easier to just hit an action. This is the world most other backends provide.
A few other thoughts:
- You can pass a whole user into an action to avoid having to do a query off the bat. Just note the data can be more stale than reading from the action. I have a
Table
helper which is useful for these situations.
- A scheduled action can still fail but you have the ID for it and can check the status with a cron or scheduled timeout mutation. And it's not going to fail at the networking layer, since the scheduler commits atomically with the other data. Scheduled mutations have automatic retries in case of database contention.Argument Validation without Repetition
In the first post in this series, the Types and Validators cookbook, we shared several basic patterns & bes...