Captain Pre
Captain Pre•7mo ago

How Do You Handle Auth? I am trying to upload user data to the database after Google OAuth.

Alright, Here is the thing. I have set up JWT Cookie Based auth using Auth Js, I simply want to store the User Data in the Database. const session = await auth(); // Gives me session.user.name, session.user.email, session.user.image I have a users.tsx :
import { mutation } from "./_generated/server";
import { v } from "convex/values";

export const createUser = mutation({
args: { email: v.string(), name: v.string(), image: v.string() },
handler: async (ctx, args) => {
const userId = await ctx.db.insert("users", {
email: args.email,
name: args.name,
image: args.image,
});
return userId;
console.log(userId);
},
});
import { mutation } from "./_generated/server";
import { v } from "convex/values";

export const createUser = mutation({
args: { email: v.string(), name: v.string(), image: v.string() },
handler: async (ctx, args) => {
const userId = await ctx.db.insert("users", {
email: args.email,
name: args.name,
image: args.image,
});
return userId;
console.log(userId);
},
});
SignIn Page :
import { signIn } from "@/auth";

export default function Home() {
return (
<>
<form
action={async () => {
"use server";
await signIn("google", { redirectTo: "/dashboard" });
}}
>
<button type="submit">Signin with Google</button>
</form>
</>
);
}
import { signIn } from "@/auth";

export default function Home() {
return (
<>
<form
action={async () => {
"use server";
await signIn("google", { redirectTo: "/dashboard" });
}}
>
<button type="submit">Signin with Google</button>
</form>
</>
);
}
as you can see users are redirected to /dashboard after successful login, Upon which i want to call the createUser() function so the userdata is stored in the database. Is this a good approach? If not, What is a simple way to make it work. Auth is already way too complicated for me. I dont want to use clerk as i have started to learn auth js and dont want to drop it.
21 Replies
ian
ian•7mo ago
Here's some resources that should cover storing users - let us know if it's still unclear https://stack.convex.dev/nextauth https://stack.convex.dev/nextauth-adapter And if you like Auth.js, you might like Convex Auth, which shares some code / concepts: https://stack.convex.dev/convex-auth
Stack
Convex with Auth.js (NextAuth)
Learn how to use Auth.js with your Next.js server and Convex backend to build a full-featured authentication system.
Stack
Convex Adapter for Auth.js (NextAuth) Setup Guide
Learn how to install and configure the Convex adapter for Auth.js as part of getting set up with Convex and Next.js.
Stack
Introducing Convex Auth
Convex Auth is a library for implementing authentication natively in your Convex backend.
Captain Pre
Captain PreOP•7mo ago
Just a question, Yet to complete the article. What is an "Database adapter"?
erquhart
erquhart•7mo ago
It's the Auth.js API for connecting to different databases - you can ignore that part if you're implementing Convex Auth.
Captain Pre
Captain PreOP•7mo ago
Makes sense, Looks like i am complicating things when there is a easier solution. My aim is to get the project out asap. I will switch to convex auth 🙂 Thanks!
erquhart
erquhart•7mo ago
Yeah if you're rolling your own solution with Auth.js, you'll love Convex Auth.
Captain Pre
Captain PreOP•7mo ago
const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string); What is this line when using clerk? I decided to go with clerk since that seemed easier. What is VITE_CONVEX_URL ?
erquhart
erquhart•7mo ago
Are you using Vite? Assuming you are, it's CONVEX_URL, but with VITE prefixed because Vite will only expose environment variables prefixed with "VITE" for security.
Captain Pre
Captain PreOP•7mo ago
Nope, I used this: const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!); my NEXT_PUBLIC_CONVEX_URL Looks something like https://xxxxxxx-xxxxxxx-xxx.convex.cloud On the right track yeah?
erquhart
erquhart•7mo ago
Are you using Vite or Next to build your site
Captain Pre
Captain PreOP•7mo ago
Next
erquhart
erquhart•7mo ago
then you're on the right track, follow the next instructions and not Vite convex.cloud is your convex url, yep
Captain Pre
Captain PreOP•7mo ago
No description
Captain Pre
Captain PreOP•7mo ago
Convex & Clerk | Convex Developer Hub
Clerk is an authentication platform providing login via
Captain Pre
Captain PreOP•7mo ago
After following these steps Attempted import error: 'SWRConfig' is not exported from 'swr' (imported as 'SWRConfig'). i did npm install @clerk/nextjs
ian
ian•7mo ago
these are set when you first run npx convex dev - and set up like regular react (step 8 here: https://docs.convex.dev/quickstart/react)
Captain Pre
Captain PreOP•7mo ago
Another question, When i am using clerk.
"use client";
import { SignInButton, UserButton } from "@clerk/nextjs";
import { Authenticated, Unauthenticated } from "convex/react";
import { Content } from "next/font/google";
import Image from "next/image";

export default function Home() {
return (
<main>
<Unauthenticated>
<SignInButton />
</Unauthenticated>
<Authenticated>
<UserButton />
</Authenticated>
</main>
);
}
"use client";
import { SignInButton, UserButton } from "@clerk/nextjs";
import { Authenticated, Unauthenticated } from "convex/react";
import { Content } from "next/font/google";
import Image from "next/image";

export default function Home() {
return (
<main>
<Unauthenticated>
<SignInButton />
</Unauthenticated>
<Authenticated>
<UserButton />
</Authenticated>
</main>
);
}
To have this functionality my page needs to Use Client Which means, All my pages will be client components? Auth is such an headache lmao 😭 Still haven’t figured out how to do it properly
import { ClerkProvider, useAuth } from "@clerk/clerk-react";
import { ConvexReactClient } from "convex/react";
import { ConvexProviderWithClerk } from "convex/react-clerk";

import React, { PropsWithChildren } from "react";

const convex = new ConvexReactClient(
process.env.NEXT_PUBLIC_CONVEX_URL as string
);

const providers = ({ children }: PropsWithChildren) => {
return (
<ClerkProvider
publishableKey={process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY!}
>
<ConvexProviderWithClerk client={convex} useAuth={useAuth}>
{children}
</ConvexProviderWithClerk>
</ClerkProvider>
);
};

export default providers;
import { ClerkProvider, useAuth } from "@clerk/clerk-react";
import { ConvexReactClient } from "convex/react";
import { ConvexProviderWithClerk } from "convex/react-clerk";

import React, { PropsWithChildren } from "react";

const convex = new ConvexReactClient(
process.env.NEXT_PUBLIC_CONVEX_URL as string
);

const providers = ({ children }: PropsWithChildren) => {
return (
<ClerkProvider
publishableKey={process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY!}
>
<ConvexProviderWithClerk client={convex} useAuth={useAuth}>
{children}
</ConvexProviderWithClerk>
</ClerkProvider>
);
};

export default providers;
What is wrong with this? I am using nextjs
ian
ian•7mo ago
I am not an expert in server components, but I thought they couldn’t use context?
Michal Srb
Michal Srb•7mo ago
@Captain Pre you need "use client" on that file. See the Next.js tab here: https://labs.convex.dev/auth/setup#set-up-the-react-provider
Set Up Convex Auth - Convex Auth
Authentication library for your Convex backend
Michal Srb
Michal Srb•7mo ago
Note that we're working on a Next.js SDK for Convex Auth that will allow you to preload data in server components (should be released in the next two weeks). But usually you don't need that, since it only affects page load performance (it's an optimization).
Captain Pre
Captain PreOP•7mo ago
Figured it, Here’s the thing. When a user signs up with clerk -> They get redirected to /dashboard -> This dashboard page is set to “use client” to call the UseEffect which calls the “storeUser()” which then adds the user to the database. The problem here is, I am forced to make /dashboard a client component. In my case, It works cause /dashboard is a client component anyways. But, What if i want my page to be a server component? This cannot be achieved with convex right now, Right? Sorry I’m on mobile, The formatting sucks
ian
ian•7mo ago
On the server use effect doesn’t do anything, but you can await a call to fetchMutation

Did you find this page helpful?