nextauthjs / next-auth

Authentication for the Web.
https://authjs.dev
ISC License
24.07k stars 3.33k forks source link

The adapter-drizzle adapter fails to compile the cloudflare Pages environment when using cloudflare D1 #11423

Open tianlelyd opened 1 month ago

tianlelyd commented 1 month ago

Adapter type

@auth/drizzle-adapter

Environment

pnpx envinfo --system --binaries --browsers --npmPackages "{next,react,next-auth,@auth/*}"
Packages: +1
+
Progress: resolved 1, reused 0, downloaded 1, added 1, done

  System:
    OS: macOS 15.0
    CPU: (8) arm64 Apple M1 Pro
    Memory: 189.94 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.14.0 - /opt/homebrew/opt/nvm/versions/node/v20.14.0/bin/node
    npm: 10.7.0 - /opt/homebrew/opt/nvm/versions/node/v20.14.0/bin/npm
    pnpm: 9.6.0 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 126.0.6478.183
    Edge: 126.0.2592.113
    Safari: 18.0
  npmPackages:
    @auth/d1-adapter: ^1.4.1 => 1.4.1
    @auth/drizzle-adapter: ^1.4.1 => 1.4.1
    next: ^14.2.0 => 14.2.5
    next-auth: 5.0.0-beta.19 => 5.0.0-beta.19
    react: ^18 => 18.3.1

Reproduction URL

https://github.com/tianlelyd/drizzle-adapter-d1-test.git

Describe the issue

When using nextjs+drizzle+auth.js+adapter-drizzle, local testing works fine, but when compiling with pnpx @cloudflare/next-on-pages@1, an error occurs indicating that "getRequestContext is being called at the top level of a route file, this is not supported". However, I am not actually calling getRequestContext() at the top level.

How to reproduce

runpnpm run pages:build

Expected behavior

It should not prompt「getRequestContext` is being called at the top level of a route file, this is not supported」

patrickgdl commented 1 month ago

I am getting a similar error, but is logs TypeError: Cannot read properties of undefined (reading 'prepare')

patrickgdl commented 1 month ago

In my case it was a missing binding to D1 database on wrangler.toml

tianlelyd commented 1 month ago

I am getting a similar error, but is logs TypeError: Cannot read properties of undefined (reading 'prepare')我收到类似的错误,但这是日志 TypeError: Cannot read properties of undefined (reading 'prepare')

You're using the D1 adapter in auth, but you're passing in a drizzle object, so you'll get the hint you said

eli-front commented 1 month ago

Solution Using "next-auth": "^5.0.0-beta.19"

  1. follow instructions https://authjs.dev/getting-started/installation?framework=next.js
  2. after getting auth.ts setup, add the Drizzle adapter
// auth.ts
import NextAuth from "next-auth"
import { DrizzleAdapter } from "@auth/drizzle-adapter"
import { drizzle } from "drizzle-orm/d1"
import { getRequestContext } from "@cloudflare/next-on-pages"
import { accounts, sessions, users, verificationTokens } from "./schema"
import GitHub from "next-auth/providers/github"

export const { handlers, auth, signIn, signOut } = NextAuth(() => {

  const db = drizzle(getRequestContext().env.DB)

  return {
    adapter: DrizzleAdapter(db, {
      usersTable: users,
      accountsTable: accounts,
      sessionsTable: sessions,
      verificationTokensTable: verificationTokens,
    }),
    session: { strategy: "jwt" },
    providers: [GitHub]
})

And then the [...nextauth]/route.ts

// [...nextauth]/route.ts
import { handlers } from "@/auth" // Referring to the auth.ts we just created
export const { GET, POST } = handlers
export const runtime = "edge" // required for cloudflare

You should be able to interact with the d1 database now (server-side)

Important There still seems to be inconsistent support for edge with this approach, but you should be able to work with D1 & drizzle. I just threw this together, may have some issues, but should have a minimal example of a functioning drizzle + d1 setup https://github.com/eli-front/next-auth-cloudflare-d1-drizzle.

ioabhishek commented 5 days ago

In my case it was a missing binding to D1 database on wrangler.toml

How you had fixed this

ioabhishek commented 5 days ago

export const db = drizzle(process.env.DB, { schema, logger: true })

patrickgdl commented 4 days ago

export const db = drizzle(process.env.DB, { schema, logger: true })

Make sure you have the DB binding in your wrangler.toml

[[d1_databases]]
binding = "DB"
database_name = "your-database-name"
ioabhishek commented 4 days ago

[[d1_databases]] binding = "DB" database_name = "cfd1"

its already done

whateverneveranywhere commented 1 hour ago

these seem to be related: https://github.com/cloudflare/next-on-pages/issues/683