TheNinjrKillr
TheNinjrKillr•9mo ago

Convex+Clerk lack of Auth within preloadQuery

I'm getting a strange error when using preloadQuery, where there is no authentication. Use of preloadQuery:
export default async function CampaignsPage() {
const { userId } = auth();

if (!userId) return redirect("/");

const preloadedCampaigns = await preloadQuery(api.db.players.getCampaigns);

return (
<CampaignPageContent
userID={userId}
preloadedCampaigns={preloadedCampaigns}
/>
);
}
export default async function CampaignsPage() {
const { userId } = auth();

if (!userId) return redirect("/");

const preloadedCampaigns = await preloadQuery(api.db.players.getCampaigns);

return (
<CampaignPageContent
userID={userId}
preloadedCampaigns={preloadedCampaigns}
/>
);
}
api.db.players.getCampaigns:
export const getCampaigns = query({
args: {},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (identity === null) {
throw new Error("Unauthenticated call to query!");
}
// Do stuff here
export const getCampaigns = query({
args: {},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (identity === null) {
throw new Error("Unauthenticated call to query!");
}
// Do stuff here
This was working perfectly when I was just using useQuery within my Client-rendered <CampaignPageContent> component. Any thoughts / advice?
No description
4 Replies
TheNinjrKillr
TheNinjrKillrOP•9mo ago
I would have thought that the auth() call returning a successful userId would mean the convex integration was going to work 🤔
TheNinjrKillr
TheNinjrKillrOP•9mo ago
Now that I've documented this, I note my one other server-side NextJS component that's trying to do Convex stuff is also failing: Component
export default async function CampaignGMPage({
params,
searchParams,
}: {
params: { id: string };
searchParams: { [key: string]: string | string[] | undefined };
}) {
const { userId } = auth();
if (!userId) return redirect("/");

if (searchParams && searchParams.goLive) {
console.log("trying to go live!");

fetchMutation(api.db.campaigns.goLive, {
campaign: params.id as Id<"campaigns">,
timestamp: BigInt(+Date.now()),
});
}

return <CampaignGMPageContent userID={userId} />;
}
export default async function CampaignGMPage({
params,
searchParams,
}: {
params: { id: string };
searchParams: { [key: string]: string | string[] | undefined };
}) {
const { userId } = auth();
if (!userId) return redirect("/");

if (searchParams && searchParams.goLive) {
console.log("trying to go live!");

fetchMutation(api.db.campaigns.goLive, {
campaign: params.id as Id<"campaigns">,
timestamp: BigInt(+Date.now()),
});
}

return <CampaignGMPageContent userID={userId} />;
}
Mutation
export const goLive = mutation({
args: {
campaign: v.id("campaigns"),
timestamp: v.int64(),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (identity === null) {
throw new Error("Unauthenticated call to mutation!");
}

// Do stuff
export const goLive = mutation({
args: {
campaign: v.id("campaigns"),
timestamp: v.int64(),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (identity === null) {
throw new Error("Unauthenticated call to mutation!");
}

// Do stuff
No description
sshader
sshader•9mo ago
Take a look at https://docs.convex.dev/client/react/nextjs/server-rendering#server-side-authentication -- I believe you need to pass your auth token to the preloadedQuery / fetchMutation calls explicitly
Next.js Server Rendering | Convex Developer Hub
Next.js automatically renders both Client and Server Components on the server
TheNinjrKillr
TheNinjrKillrOP•9mo ago
😮 Oh my lord, you're a star! Thanks @sshader

Did you find this page helpful?