NlaakALD
NlaakALD•3mo ago

Server show signed in & refreshed token, yet, <Unauthenticated> is triggered

What am I missing here? I'm just trying to use Email/Password Signup & Register. Nothing else. Not using OAuth. Been working fine for months with Clerk. I am trying to migrate to Convex Auth. The project is huge so i did screen shots and compressed the user functions (partial) and user schema into a single TS file. The server is configured, tables, env, keys. It looks like its working but there is some disconnected with the Provider/Context?
16 Replies
Convex Bot
Convex Bot•3mo 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!
NlaakALD
NlaakALDOP•3mo ago
No guesses? Try support?
sshader
sshader•3mo ago
A couple weird things in the set up that may or may not be related to what you're seeing: * What's NEXT_PUBLIC_CLERK_DOMAIN? Is it just an old variable name that is actually set to be your .convex.site URL like Convex Auth requires? * The getAccessToken function in the auth.ts seems wrong -- that's not returning an access token, it's returning a token identifier which is different. What's the page that's showing "Not Authenticated"? Is it server rendered or client rendered? Is this just going off of useConvexAuth / isAuthenticatedNextjs, or something more sophisticated? I'd also suggest temporarily enabling verbose logging to get more insight into what exactly might be happening here (https://labs.convex.dev/auth/debugging#enabling-verbose-logging)
Debugging - Convex Auth
Authentication library for your Convex backend
NlaakALD
NlaakALDOP•3mo ago
1. NEXT_PUBLIC_CLERK_DOMAIN is left over from converting. CLERK removed 2. "Not Authenticated" is the landing page for Messenger. Auth Route. I converted it and was testinging the <Authenticated> <Unauthenticated> <AuthLoading> etc before I convert the rest. Very big app. I have been in Convex Auth Docs for days. I have this working on 3 other sites, but its the basic. For this App I am trying to Auth Server Side, but expose the User data to the page/components clients side. So, I need the User and info from Admin and Subscription tables to be available. The others do not do that yet. they are basic at this time i have it all broke because i tried going back to the basics to see if i could get this to work correctly.
"use client";

import LoaderSpinner from "@/components/LoaderSpinner";
import React from "react";
import Feed from '@/components/credo/Feed';
import StandardHeader from "@/components/StandardHeader";
import { UpgradeRequired } from "@/components/UpgradeRequired";
import { CreateTwirp } from "@/components/credo/CreateTwirp";
import { AnalyticsTracker } from "@/components/app/AnalyticsTracker";
//import { Authenticated, AuthLoading, Unauthenticated } from "@/providers/ConvexAuthProvider";
import { Authenticated, AuthLoading, Unauthenticated } from "convex/react";


const CredoPage: React.FC = () => {

// if (!userInfo.convexUser) {
// return <UpgradeRequired feature="Credo" subscriptionLevel={0} />;
// }

return (
<div className="flex flex-col h-full">
<AuthLoading>
<LoaderSpinner />
</AuthLoading>

<Authenticated>
<AnalyticsTracker />
<StandardHeader headerText="Credo" outline={false} />
<div className="flex-grow overflow-y-auto px-4">
<Feed />
</div>
<div className="p-4 border-t">
<CreateTwirp />
</div>
</Authenticated>
<Unauthenticated>
<p>Not Authenticated</p>
</Unauthenticated>
</div>
);
}

export default CredoPage;
"use client";

import LoaderSpinner from "@/components/LoaderSpinner";
import React from "react";
import Feed from '@/components/credo/Feed';
import StandardHeader from "@/components/StandardHeader";
import { UpgradeRequired } from "@/components/UpgradeRequired";
import { CreateTwirp } from "@/components/credo/CreateTwirp";
import { AnalyticsTracker } from "@/components/app/AnalyticsTracker";
//import { Authenticated, AuthLoading, Unauthenticated } from "@/providers/ConvexAuthProvider";
import { Authenticated, AuthLoading, Unauthenticated } from "convex/react";


const CredoPage: React.FC = () => {

// if (!userInfo.convexUser) {
// return <UpgradeRequired feature="Credo" subscriptionLevel={0} />;
// }

return (
<div className="flex flex-col h-full">
<AuthLoading>
<LoaderSpinner />
</AuthLoading>

<Authenticated>
<AnalyticsTracker />
<StandardHeader headerText="Credo" outline={false} />
<div className="flex-grow overflow-y-auto px-4">
<Feed />
</div>
<div className="p-4 border-t">
<CreateTwirp />
</div>
</Authenticated>
<Unauthenticated>
<p>Not Authenticated</p>
</Unauthenticated>
</div>
);
}

export default CredoPage;
now i have an absolute mess 😦 i guess i should just create a function to lookup and return what i need and call it from the components?
erquhart
erquhart•3mo ago
Can you try some logging in your custom auth provider to see if authentication state is ever being properly captured client side? App size aside, this looks like it should still be a pretty straightforward nextjs integration for auth.
NlaakALD
NlaakALDOP•3mo ago
yeah. give me a few. ill have to create another branch and reimplement. @erquhart re: "authentication state is ever being properly captured client side?" altualy its not. isAuthenticated is false
NlaakALD
NlaakALDOP•3mo ago
wow. i am stumped. Here is the latest. logs, relevant files... user.ts:getCurrentUser()
export const getCurrentUser = query({
args: {},
handler: async (ctx) => {
debug("getCurrentUser:","start");

const identity = await ctx.auth.getUserIdentity();
if (!identity) {
return null;
}
debug("getCurrentUser->identity:",JSON.stringify(identity));

const user = await ctx.db
.query('users')
.filter(q => q.eq(q.field('email'), identity.email))
.first();

if (!user) {
return null;
}
debug("getCurrentUser->user:",JSON.stringify(user));

// Check admin status
const isAdmin = await ctx.db
.query("admins")
.withIndex("by_userId")
.filter(q => q.eq(q.field("userId"), user._id))
.first();

debug("getCurrentUser->isAdmin:",JSON.stringify(isAdmin));

debug("getCurrentUser:","done");
return {
_id: user._id,
email: user.email,
phone: user.phone,
imageUrl: user.imageUrl,
bgImageUrl: user.bgImageUrl,
bgImageStorageId: user.bgImageStorageId,
bgImageOpacity: user.bgImageOpacity,
clerkId: user.clerkId, // TODO: Remove after migration to Convex Auth
name: user.name,
username: user.username,
bio: user.bio,
credits: user.credits,
ghostArtist: user.ghostArtist,
ghostWriter: user.ghostWriter,
totalViews: user.totalViews,
subscriptionLevel: user.subscriptionLevel,
isAnonymous: user.isAnonymous,
isAdmin: !!isAdmin, // Set based on the presence of an admin record
unreadMessages: user.unreadMessages,
emailVerificationTime: user.emailVerificationTime,
phoneVerificationTime: user.phoneVerificationTime,
lastLoginDate: user.lastLoginDate,
};
},
});
export const getCurrentUser = query({
args: {},
handler: async (ctx) => {
debug("getCurrentUser:","start");

const identity = await ctx.auth.getUserIdentity();
if (!identity) {
return null;
}
debug("getCurrentUser->identity:",JSON.stringify(identity));

const user = await ctx.db
.query('users')
.filter(q => q.eq(q.field('email'), identity.email))
.first();

if (!user) {
return null;
}
debug("getCurrentUser->user:",JSON.stringify(user));

// Check admin status
const isAdmin = await ctx.db
.query("admins")
.withIndex("by_userId")
.filter(q => q.eq(q.field("userId"), user._id))
.first();

debug("getCurrentUser->isAdmin:",JSON.stringify(isAdmin));

debug("getCurrentUser:","done");
return {
_id: user._id,
email: user.email,
phone: user.phone,
imageUrl: user.imageUrl,
bgImageUrl: user.bgImageUrl,
bgImageStorageId: user.bgImageStorageId,
bgImageOpacity: user.bgImageOpacity,
clerkId: user.clerkId, // TODO: Remove after migration to Convex Auth
name: user.name,
username: user.username,
bio: user.bio,
credits: user.credits,
ghostArtist: user.ghostArtist,
ghostWriter: user.ghostWriter,
totalViews: user.totalViews,
subscriptionLevel: user.subscriptionLevel,
isAnonymous: user.isAnonymous,
isAdmin: !!isAdmin, // Set based on the presence of an admin record
unreadMessages: user.unreadMessages,
emailVerificationTime: user.emailVerificationTime,
phoneVerificationTime: user.phoneVerificationTime,
lastLoginDate: user.lastLoginDate,
};
},
});
NlaakALD
NlaakALDOP•3mo ago
oh, debug func (doubt you need it)
/**
* A utility function for logging debug information in development environments.
*
* This function logs messages to the console, but only when the application
* is running in a development environment. It's useful for debugging and
* tracking application flow without cluttering production logs.
*
* @param {string} name - The name or identifier for the debug message.
* This could be a component name, function name,
* or any string that helps identify where the debug
* message is coming from.
*
* @param {string} event - The actual debug message or event description.
* This should contain the information you want to log.
*
* @example
* // Usage in a component
* debug("UserProfile", "Fetching user data");
*
* @example
* // Usage in a function
* debug("calculateTotalPrice", `Input values: ${price}, ${quantity}`);
*
* @returns {void}
*
* @remarks
* - This function only logs messages when NODE_ENV is set to 'development'.
* - In production builds, this function will not output anything, ensuring
* no debug messages are accidentally exposed in production environments.
* - The output format is: "<name>: <event>"
*/
export function debug(name: string, event: string): void {
if (process.env.NODE_ENV === 'development') {
console.log(`${name}: ${event}`);
}
}
/**
* A utility function for logging debug information in development environments.
*
* This function logs messages to the console, but only when the application
* is running in a development environment. It's useful for debugging and
* tracking application flow without cluttering production logs.
*
* @param {string} name - The name or identifier for the debug message.
* This could be a component name, function name,
* or any string that helps identify where the debug
* message is coming from.
*
* @param {string} event - The actual debug message or event description.
* This should contain the information you want to log.
*
* @example
* // Usage in a component
* debug("UserProfile", "Fetching user data");
*
* @example
* // Usage in a function
* debug("calculateTotalPrice", `Input values: ${price}, ${quantity}`);
*
* @returns {void}
*
* @remarks
* - This function only logs messages when NODE_ENV is set to 'development'.
* - In production builds, this function will not output anything, ensuring
* no debug messages are accidentally exposed in production environments.
* - The output format is: "<name>: <event>"
*/
export function debug(name: string, event: string): void {
if (process.env.NODE_ENV === 'development') {
console.log(`${name}: ${event}`);
}
}
sshader
sshader•3mo ago
Failed to authenticate: "No auth provider found matching the given token", check your server auth config is buried in your logs. Follow the step here to check that the JWT you have in your cookies matches up with the auth providers configured for your deployment (I'm about to make a more interactive way of testing this out)
Debugging Authentication | Convex Developer Hub
You have followed one of our authentication guides but something is not working.
NlaakALD
NlaakALDOP•3mo ago
NlaakALD
NlaakALDOP•3mo ago
@sshader hmmm - actually you are correct. I compared to repo last commit
const authConfig = {
providers: [
{
domain: process.env.NEXT_PUBLIC_CLERK_DOMAIN as string,
applicationID: "convex",
},
]
};

export default authConfig;
const authConfig = {
providers: [
{
domain: process.env.NEXT_PUBLIC_CLERK_DOMAIN as string,
applicationID: "convex",
},
]
};

export default authConfig;
NEXT_PUBLIC_CLERK_DOMAIN not CONVEX_SITE_URL and i did not have my npx convex dev running in second terminal as i usually do. after running that it worked and kept redirecting. Did dome rewrite on middleware and now it is working. Let me work out all the kinks and clean up the code and I'll create a working example for everyone. @sshader @erquhart Thank you for help
erquhart
erquhart•3mo ago
Glad it's working! So you needed to switch the clerk variable for the convex site variable right? For the dev process, I very much recommend having a single command for local dev that runs your client and convex together for this reason. The false positives in your first image definitely didn't help the process, though, wonder how anything had an authenticated state server time if the domain variable was wrong.
NlaakALD
NlaakALDOP•3mo ago
yes. well, i had switched it but did not update convex (npx convex dev) was not running in seperating terminal - so it did not update if any lesson for this right off the top of my head for others is ALWAYS make sure you have npx convex dev running in a separate terminal...even if you think you will not make changes to that. That way your used to it syncing automatically...and you wont waste 1.5 days 🙂 so now, i need to convert this HUGE app over this week, then QA. When done i'll post it to Show and Tell - 100% NextJS/Convex+Auth
jamwt
jamwt•3mo ago
npx convex dev is love, npx convex dev is life
Olamide
Olamide•3mo ago
I just use concurrently and run the dev server and convex running at the same time
NlaakALD
NlaakALDOP•3mo ago
i do too. i stopped it instad of npm run dev to install / remove a package and never restarted it lol

Did you find this page helpful?