To get the current user in a reusable way in Convex, you can create a helper function that can be used across your queries and mutations. Here's how you can modify your code to achieve this:
- First, create a helper function in a separate file, let's call it
userHelpers.ts:
import { QueryCtx } from "./_generated/server";
import { getAuthUserId } from "@convex-dev/auth/server";
import { ConvexError } from "convex/values";
export async function getCurrentUserOrThrow(ctx: QueryCtx) {
const userId = await getAuthUserId(ctx);
if (userId === null) {
throw new ConvexError("Not authenticated");
}
const user = await ctx.db.get(userId);
if (!user) {
throw new ConvexError("User not found");
}
return user;
}
- Now, you can use this helper function in your mutation:
import { mutation } from "./_generated/server";
import { v } from "convex/values";
import { BookingStatus, BookingType } from "./lib/bookings";
import { getCurrentUserOrThrow } from "./userHelpers";
export const create = mutation({
args: {
tutor: v.id("users"),
service: v.id("tutors_services"),
type: v.union(
v.literal(BookingType.FREE_MEETING),
v.literal(BookingType.LESSON)
),
startTime: v.number(),
endTime: v.number(),
},
handler: async (ctx, args) => {
const user = await getCurrentUserOrThrow(ctx);
const booking = await ctx.db.insert("bookings", {
student: user._id,
tutor: args.tutor,
service: args.service,
type: args.type,
status: BookingStatus.AWAITING_TUTOR_CONFIRMATION,
startTime: args.startTime,
endTime: args.endTime,
createdAt: Date.now(),
updatedAt: Date.now(),
});
return booking;
},
});
This approach has several advantages: