lolu
lolu2w ago

getAuthUserId() Returns Null Despite Successful OAuth Sign-In

getAuthUserId() Returns Null Despite Successful OAuth Sign-In Issue: getAuthUserId(ctx) returns null in all backend queries/mutations, even though OAuth sign-in succeeds and creates a valid session. Environment: - @convex-dev/auth: ^0.0.90 - Auth provider: Google OAuth What Works: - ✅ OAuth sign-in completes - ✅ Session created in authSessions table - ✅ JWT stored in browser localStorage What Doesn't Work: - ❌ getAuthUserId(ctx) returns null - ❌ ctx.auth._token is undefined (JWT not sent with requests) Code: Frontend (with useConvexAuth):
const { isAuthenticated, isLoading } = useConvexAuth();
const userProfile = useQuery(api.users.getCurrentUserProfile, isAuthenticated ? {} : "skip");
const { isAuthenticated, isLoading } = useConvexAuth();
const userProfile = useQuery(api.users.getCurrentUserProfile, isAuthenticated ? {} : "skip");
Backend:
export const getCurrentUserProfile = query({
handler: async (ctx) => {
const userId = await getAuthUserId(ctx); // Returns null!
if (userId === null) return null;
return await ctx.db.get(userId);
},
});
export const getCurrentUserProfile = query({
handler: async (ctx) => {
const userId = await getAuthUserId(ctx); // Returns null!
if (userId === null) return null;
return await ctx.db.get(userId);
},
});
Logs:
[createOrUpdateUser] Returning user ID: 'k578y1k2dpbn09n6d3m725hcfs7tcx0f' ✅
[auth:store] type: verifyCodeAndSignIn ✅
[getCurrentUserProfile] userId: null ❌
[createOrUpdateUser] Returning user ID: 'k578y1k2dpbn09n6d3m725hcfs7tcx0f' ✅
[auth:store] type: verifyCodeAndSignIn ✅
[getCurrentUserProfile] userId: null ❌
What We've Tried: - Implemented useConvexAuth() to wait for isAuthenticated: true before calling queries - Verified JWT exists in localStorage - Cleared all sessions and signed in fresh multiple times - Used getAuthUserId() from @convex-dev/auth/server Our auth.config.ts has domain: process.env.CONVEX_SITE_URL which may be undefined. Could this be blocking JWT validation? How should we properly configure authentication?
3 Replies
Convex Bot
Convex Bot2w ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
erquhart
erquhart2w ago
If isAuthenticated from useConvexAuth is true, jwt validation is working - you should see Authentication messages in the sync websocket connection with a jwt. If you have a minimal repro I can take a look.
lolu
loluOP2w ago
Minimal Reproduction Files 1. convex/auth.config.ts:
export default {
providers: [
{
domain: process.env.CONVEX_SITE_URL,
applicationID: "convex",
},
],
};
export default {
providers: [
{
domain: process.env.CONVEX_SITE_URL,
applicationID: "convex",
},
],
};
2. convex/auth.js:
import { convexAuth } from "@convex-dev/auth/server";
import Google from "@auth/core/providers/google";

export const { auth, signIn, signOut, store } = convexAuth({
providers: [Google],
callbacks: {
async createOrUpdateUser(ctx, args) {
const email = args.profile?.email;
const user = await ctx.db.query("users").withIndex("email", (q) => q.eq("email", email)).first();
console.log("[createOrUpdateUser] Returning user ID:", user?._id);
return user._id;
},
},
});
import { convexAuth } from "@convex-dev/auth/server";
import Google from "@auth/core/providers/google";

export const { auth, signIn, signOut, store } = convexAuth({
providers: [Google],
callbacks: {
async createOrUpdateUser(ctx, args) {
const email = args.profile?.email;
const user = await ctx.db.query("users").withIndex("email", (q) => q.eq("email", email)).first();
console.log("[createOrUpdateUser] Returning user ID:", user?._id);
return user._id;
},
},
});
3. convex/users.ts (query):
import { getAuthUserId } from "@convex-dev/auth/server";
import { query } from "./_generated/server";

export const getCurrentUserProfile = query({
handler: async (ctx) => {
const userId = await getAuthUserId(ctx);
console.log("[getCurrentUserProfile] userId:", userId);
if (userId === null) return null;
return await ctx.db.get(userId);
},
});
import { getAuthUserId } from "@convex-dev/auth/server";
import { query } from "./_generated/server";

export const getCurrentUserProfile = query({
handler: async (ctx) => {
const userId = await getAuthUserId(ctx);
console.log("[getCurrentUserProfile] userId:", userId);
if (userId === null) return null;
return await ctx.db.get(userId);
},
});
4. Frontend: AuthContext.jsx (React):
import { useConvexAuth } from "@convex-dev/auth/react";
import { useQuery } from "convex/react";

export function AuthProvider({ children }) {
const { isAuthenticated, isLoading } = useConvexAuth();
console.log("isAuthenticated:", isAuthenticated, "isLoading:", isLoading);

const userProfile = useQuery(
api.users.getCurrentUserProfile,
isAuthenticated ? {} : "skip"
);

console.log("userProfile:", userProfile);
// ... rest of component
}
import { useConvexAuth } from "@convex-dev/auth/react";
import { useQuery } from "convex/react";

export function AuthProvider({ children }) {
const { isAuthenticated, isLoading } = useConvexAuth();
console.log("isAuthenticated:", isAuthenticated, "isLoading:", isLoading);

const userProfile = useQuery(
api.users.getCurrentUserProfile,
isAuthenticated ? {} : "skip"
);

console.log("userProfile:", userProfile);
// ... rest of component
}
Observed Behavior: - isAuthenticated: true after sign-in ✅ - [createOrUpdateUser] logs show correct user ID ✅ - [getCurrentUserProfile] userId: null ❌ - JWT exists in localStorage ✅ @erquhart I don't know if this helps to repro.

Did you find this page helpful?