#Drizzle and NextAuth (trying to leave Supabase)

34 messages · Page 1 of 1 (latest)

late sequoia
#

Okay (hello @tidal kayak ) I have my all app build with Supabase. But I wanna something very "modular" so being stuck on Supabase isnt a good idea, that why I wnana switch with a default postgres database, so I need an ORM and NextAuth. Well lets try Drizzle (Prisma sound good too but many people say that Drizzle is more future proof). Firstly, Ive setup my Drizzle schema. I have 3 files inside @/db/schema/ :

  • index.ts
  • auth.ts
  • public.ts
    My idea is to have a seperate schema only for auth table (like Supabase does and allows me to keep seperate sensible data like password etc...). So the index.ts file only concatenate the two schema like this :
import * as publicSchema from '@/db/schema/public'

const schema = {
    ...authSchema,
    ...publicSchema,
}

export default schema;```
Ive setup my "db" like this (ive previously try to setup with Neon but got TS error without any fancy stuff just the official docs ahah) :
```import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import schema from '@/db/schema'

const connectionString = String(process.env.DATABASE_URL)
const client = postgres(connectionString)

export const db = drizzle(client, { schema });```
gentle ginkgoBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

tidal kayak
#

what's inside your authSchema and what kind of errors do you get? Where does "String" coming from? How does your "publicSchema" look like right now?

late sequoia
#

Well right now the schema seems to work, the first problem is with my "users" table when I use the serial function for generating a random uuid, but I have this error when try to push change inside db : error: type "serial" does not exist
There is my auth schema :

#
    timestamp,
    text,
    primaryKey,
  integer,
  pgSchema,
  serial
} from "drizzle-orm/pg-core"
import type { AdapterAccount } from '@auth/core/adapters'

export const authSchema = pgSchema("auth")
  
export const users = authSchema.table("users", {
  id: serial("id").primaryKey(),
  email: text("email").notNull(),
  email_verified: timestamp("email_verified", { mode: "date" }),
  password: text("password"),
  last_sign_in: timestamp("last_sign_in", { mode: "date" }),
  create_at: timestamp("create_at", { mode: "date" }),
  update_at: timestamp("update_at", { mode: "date" }),
})
  
export const accounts = authSchema.table("account", {
  userId: text("userId")
    .notNull()
    .references(() => users.id, { onDelete: "cascade" }),
  type: text("type").$type<AdapterAccount["type"]>().notNull(),
  provider: text("provider").notNull(),
  providerAccountId: text("providerAccountId").notNull(),
  refresh_token: text("refresh_token"),
  access_token: text("access_token"),
  expires_at: integer("expires_at"),
  token_type: text("token_type"),
  scope: text("scope"),
  id_token: text("id_token"),
  session_state: text("session_state"),
},
  (account) => ({
    compoundKey: primaryKey({ columns: [account.provider, account.providerAccountId] }),
  })
)
  
export const sessions = authSchema.table("session", {
  sessionToken: text("sessionToken").notNull().primaryKey(),
  userId: text("userId")
    .notNull()
    .references(() => users.id, { onDelete: "cascade" }),
  expires: timestamp("expires", { mode: "date" }).notNull(),
})
  
export const verificationTokens = authSchema.table("verificationToken", {
  identifier: text("identifier").notNull(),
  token: text("token").notNull(),
  expires: timestamp("expires", { mode: "date" }).notNull(),
},
  (vt) => ({
  compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
  })
)```
tidal kayak
late sequoia
tidal kayak
#

do you have data inside the table that needs the id column?

late sequoia
tidal kayak
#

yes

late sequoia
#

Okay now I can try to setup the NextAuth with it

tidal kayak
#

sometimes its the best to just create a new database, model all your tables, relations, foreignkeys, primarykeys, ... and after you done that, you can push the schema

late sequoia
#

When I do this :

    adapter: DrizzleAdapter(db),```
Ive got an ts error in adapter :
```Type 'import("/Users/loup/Projects/DEV/Recomend/recomend-web-app/node_modules/@auth/core/adapters").Adapter' is not assignable to type 'import("/Users/loup/Projects/DEV/Recomend/recomend-web-app/node_modules/next-auth/adapters").Adapter'.
  Types of property 'createUser' are incompatible.
    Type '((user: AdapterUser) => Awaitable<AdapterUser>) | undefined' is not assignable to type '((user: Omit<AdapterUser, "id">) => Awaitable<AdapterUser>) | undefined'.
      Type '(user: AdapterUser) => Awaitable<AdapterUser>' is not assignable to type '(user: Omit<AdapterUser, "id">) => Awaitable<AdapterUser>'.
        Types of parameters 'user' and 'user' are incompatible.
          Property 'id' is missing in type 'Omit<AdapterUser, "id">' but required in type 'AdapterUser'.ts(2322)
adapters.d.ts(174, 5): 'id' is declared here.
types.d.ts(106, 5): The expected type comes from property 'adapter' which is declared here on type 'AuthOptions'```
And the docs say if u have multiple schemas, u should add inside DrizzleAdapter the schema like this I guess :
`adapter: DrizzleAdapter(db, { schema }),`
But I got another error in schema : `Object literal may only specify known properties, and 'schema' does not exist in type 'PgTableFn<undefined>'.`
tidal kayak
#

can I see your imports please?

late sequoia
# tidal kayak can I see your imports please?

Sure, there is my auth.ts :

import { db } from "@/db";
import schema from "@/db/schema";

export const authOptions: NextAuthOptions = {
    adapter: DrizzleAdapter(db, { schema }),
    secret: process.env.NEXTAUTH_SECRET,
// ...```
And `@/db/index.ts` :
```import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import schema from '@/db/schema'

const connectionString = String(process.env.DATABASE_URL)
const client = postgres(connectionString)

export const db = drizzle(client, { schema });```
tidal kayak
late sequoia
#

There is my import :
`import { NextAuthOptions } from "next-auth";
import { DrizzleAdapter } from "@auth/drizzle-adapter"
import { compare } from "bcrypt";

// Providers
import CredentialsProvider from "next-auth/providers/credentials";
import GithubProvider from "next-auth/providers/github";
import { db } from "@/db";
import schema from "@/db/schema";`

#

Ive got the same error with the default example from AuthJS :
export default NextAuth({ adapter: DrizzleAdapter(db), providers: [ GithubProvider({ clientId: process.env.NEXTAUTH_GITHUB_ID as string, clientSecret: process.env.NEXTAUTH_GITHUB_SECRET as string, }), ], })

strange cove
strange cove
#

yes then use "0.29.3" without the ^

late sequoia
#

Dumby question, but how can I update the change ?

strange cove
#

go to package.json, change "^0.29.4" to "0.29.3", run npm install again

late sequoia
# strange cove go to `package.json`, change `"^0.29.4"` to `"0.29.3"`, run `npm install` again

Well still having same problem, its propably due to my schema because the error is this :
Type 'import("/Users/loup/Projects/DEV/Recomend/recomend-web-app/node_modules/@auth/core/adapters").Adapter' is not assignable to type 'import("/Users/loup/Projects/DEV/Recomend/recomend-web-app/node_modules/next-auth/adapters").Adapter'. Types of property 'createUser' are incompatible. Type '((user: AdapterUser) => Awaitable<AdapterUser>) | undefined' is not assignable to type '((user: Omit<AdapterUser, "id">) => Awaitable<AdapterUser>) | undefined'. Type '(user: AdapterUser) => Awaitable<AdapterUser>' is not assignable to type '(user: Omit<AdapterUser, "id">) => Awaitable<AdapterUser>'. Types of parameters 'user' and 'user' are incompatible. Property 'id' is missing in type 'Omit<AdapterUser, "id">' but required in type 'AdapterUser'.ts(2322) adapters.d.ts(174, 5): 'id' is declared here. types.d.ts(106, 5): The expected type comes from property 'adapter' which is declared here on type 'AuthOptions'

#

okay I guess I found, I have a custom table "user" in public schema, but I was thinking that the adapter use table "users" but no, in the adapter I can see this :
export function createTables(pgTable: PgTableFn) { const users = pgTable("user", { id: text("id").notNull().primaryKey(), name: text("name"), email: text("email").notNull(), emailVerified: timestamp("emailVerified", { mode: "date" }), image: text("image"), })

So there is a conflict between my custom table user and the user one for auth

#

I guess we cant custom the target table from DrizzleAdapter

strange cove
late sequoia
late sequoia
#

Well heaven with a custom adapter I still getting the same issue from adapter

#

anyway I just gonna put a ts-ignore for this

late sequoia
#

okay we only have an array as return value, that quite frustating

late sequoia
#

I try to extend my Next Auth session with all user data, but where can I get the type from schema ?