Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prisma Client Doesn't Recognize Accelerate #23993

Open
DarkerMinecraft opened this issue Apr 26, 2024 · 5 comments
Open

Prisma Client Doesn't Recognize Accelerate #23993

DarkerMinecraft opened this issue Apr 26, 2024 · 5 comments
Labels
bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. kind/bug A reported bug. team/client Issue for team Client. topic: pdp/accelerate

Comments

@DarkerMinecraft
Copy link

DarkerMinecraft commented Apr 26, 2024

Bug description

I'm using NextAuth for authentication and using Prisma to manage it. I switched to Prisma Accelerate because I wanted to access db stuff within the middleware.

So I went, and I extended it with Accelerate, and I get this error:

 PrismaClient is not configured to run in Vercel Edge Functions or Edge Middleware. In order to run Prisma Client on edge runtime, either:
- Use Prisma Accelerate: https://pris.ly/d/accelerate
- Use Driver Adapters: https://pris.ly/d/driver-adapters

How to reproduce

Setup the database connection like this

import { PrismaClient } from "@prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";

declare global {
  var prisma: any | undefined;
}

export const db =
  globalThis.prisma || new PrismaClient().$extends(withAccelerate());

if (process.env.NODE_ENV !== "production") globalThis.prisma = db;

Expected behavior

Middleware should be working with Accelerate and Prisma should be able to detect it.

Prisma information

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}

model Account {
  id                String  @id @default(cuid())
  userId            String
  type              String
  provider          String
  providerAccountId String
  refresh_token     String? @db.Text
  access_token      String? @db.Text
  expires_at        Int?
  token_type        String?
  scope             String?
  id_token          String? @db.Text
  session_state     String?

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([provider, providerAccountId])
}

model User {
  id                    String                 @id @unique @default(cuid())
  name                  String
  email                 String?                @unique
  emailVerified         DateTime?
  image                 String?
  banner                String?
  password              String?
  accountTypeId         Int                    @default(1)
  bio                   String?
  accounts              Account[]
  isTwoFactorEnabled    Boolean                @default(false)
  twoFactorConfirmation TwoFactorConfirmation?
  articles              Article[]

  following Follow[] @relation("Following")
  followers Follow[] @relation("FollowedBy")

  blocking  Block[] @relation("Blocking")
  blockedBy Block[] @relation("BlockedBy")

  accountType AccountType @relation(fields: [accountTypeId], references: [id], onDelete: Cascade)
  likes       Like[]
  comments    Comment[]
  stream      Stream?
  dislikes    DisLike[]
  createdAt   DateTime    @default(now())
  ban         Ban?
  videos      Video[]
}

model Stream {
  id        String  @id @default(cuid())
  name      String  @db.Text
  thumbnail String? @db.Text

  ingressId String? @unique
  serverUrl String? @db.Text
  streamKey String? @db.Text

  isLive              Boolean @default(false)
  isChatEnabled       Boolean @default(true)
  isChatDelay         Boolean @default(false)
  isChatFollowersOnly Boolean @default(false)

  description String? @db.Text

  userId String @unique
  user   User   @relation(fields: [userId], references: [id], onDelete: Cascade)

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@index([userId])
  @@index([ingressId])
}

model Follow {
  id          String @id @default(cuid())
  followerId  String
  followingId String

  follower  User @relation(name: "Following", fields: [followerId], references: [id], onDelete: Cascade)
  following User @relation(name: "FollowedBy", fields: [followingId], references: [id], onDelete: Cascade)

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@unique([followerId, followingId])
  @@index([followerId, followingId], name: "unique_follow")
}

model Block {
  id        String @id @default(cuid())
  blockerId String
  blockedId String

  blocker User @relation(name: "Blocking", fields: [blockerId], references: [id], onDelete: Cascade)
  blocked User @relation(name: "BlockedBy", fields: [blockedId], references: [id], onDelete: Cascade)

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@unique([blockedId, blockerId])
  @@index([blockedId, blockerId], name: "unique_block")
}

model AccountType {
  id   Int    @id @unique @default(autoincrement())
  name String @unique
  User User[]
}

model Ban {
  id        String   @id @default(cuid())
  userId    String
  reason    String
  expiresAt DateTime

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([userId])
}

model VerificationToken {
  id      String   @id @default(cuid())
  email   String
  token   String   @unique
  expires DateTime

  @@unique([email, token])
}

model PasswordResetToken {
  id      String   @id @default(cuid())
  email   String
  token   String   @unique
  expires DateTime

  @@unique([email, token])
}

model TwoFactorToken {
  id      String   @id @default(cuid())
  email   String
  token   String   @unique
  expires DateTime

  @@unique([email, token])
}

model TwoFactorConfirmation {
  id String @id @default(cuid())

  userId String
  user   User   @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([userId])
}

model Article {
  id        String    @id @default(cuid())
  title     String    @unique
  thumbnail String?
  content   Json?
  author    User      @relation(fields: [authorId], references: [id], onDelete: Cascade)
  authorId  String
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  likes     Like[]
  dislikes  DisLike[]
  comments  Comment[]
  summary   String    @default("") @db.Text
}

model Video {
  id           String @id @default(cuid())
  title        String
  description  String @db.Text
  videoUrl     String
  thumbnailUrl String

  userId    String
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  createdAt DateTime @default(now())

  likes    Like[]
  dislikes DisLike[]
  comments Comment[]
}

model VisibilityType {
  id   Int    @id @unique @default(autoincrement())
  name String @unique
}

model Like {
  id String @id @default(cuid())

  article   Article? @relation(fields: [articleId], references: [id])
  articleId String?

  video   Video?  @relation(fields: [videoId], references: [id], onDelete: Cascade)
  videoId String?

  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId    String
  createdAt DateTime @default(now())
}

model DisLike {
  id String @id @default(cuid())

  article   Article? @relation(fields: [articleId], references: [id], onDelete: Cascade)
  articleId String?

  video   Video?  @relation(fields: [videoId], references: [id], onDelete: Cascade)
  videoId String?

  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId    String
  createdAt DateTime @default(now())
}

model Comment {
  id String @id @default(cuid())

  article   Article? @relation(fields: [articleId], references: [id], onDelete: Cascade)
  articleId String?
  video     Video?   @relation(fields: [videoId], references: [id], onDelete: Cascade)
  videoId   String?

  user     User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  userId   String
  content  String
  parent   Comment?  @relation(name: "Parent", fields: [parentId], references: [id], onDelete: Cascade)
  parentId String?
  children Comment[] @relation("Parent")

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model Analytics {
  id String @id @default(cuid())

  namespace String
  event     Json?
  count     Int
}
import bcrypt from "bcrypt-edge";
import type { NextAuthConfig } from "next-auth";
import Credentials from "next-auth/providers/credentials";
import Google from "next-auth/providers/google";

import { LoginSchema } from "@/schemas";
import { getUserByEmail } from "@/data/user";

export default {
  providers: [
    Credentials({
      async authorize(credentials) {
        const validatedFields = LoginSchema.safeParse(credentials);

        if (validatedFields.success) {
          const { email, password } = validatedFields.data;

          const user = await getUserByEmail(email);
          if (!user || !user.password) return null;

          const passwordsMatch = bcrypt.compareSync(password, user.password);

          if (passwordsMatch) return user;
        }

        return null;
      },
    }),
    Google({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
} satisfies NextAuthConfig;

Environment & setup

  • OS: Windows & Ubuntu
  • Database: PostgreSQL
  • Node.js version: v21.7.3

Prisma Version

prisma                  : 5.13.0
@prisma/client          : 5.13.0
Computed binaryTarget   : windows
Operating System        : win32
Architecture            : x64
Node.js                 : v21.7.3
Query Engine (Node-API) : libquery-engine b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b (at node_modules\@prisma\engines\query_engine-windows.dll.node)
Schema Engine           : schema-engine-cli b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b (at node_modules\@prisma\engines\schema-engine-windows.exe)
Schema Wasm             : @prisma/prisma-schema-wasm 5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b
Default Engines Hash    : b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b
Studio                  : 0.500.0
@janpio
Copy link
Member

janpio commented Apr 26, 2024

Try this import for an edge runtime, like NextAuth seems to be using in your case: import { PrismaClient } from '@prisma/client/edge'

@SevInf SevInf added bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. team/client Issue for team Client. labels Apr 29, 2024
@SevInf
Copy link
Contributor

SevInf commented Apr 29, 2024

Also, please make sure you are using prisma:// url as your connection string - extension alone is not enough to get accelerate working.

@DarkerMinecraft
Copy link
Author

I don't want to use the edge runtime because the NextAuth doesn't work when I do. Also I am using the prisma://

@janpio
Copy link
Member

janpio commented Apr 30, 2024

The error message you are getting is telling you that the code is being executed in the Edge Runtime though. (Next.js middlewares are always executed in that even when you run in locally in Node for example: https://nextjs.org/docs/app/building-your-application/routing/middleware#runtime - and I assume that is what is being used here under the hood by NextAuth or Next.js)

@nurul3101
Copy link
Member

@DarkerMinecraft Are you still running into this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. kind/bug A reported bug. team/client Issue for team Client. topic: pdp/accelerate
Projects
None yet
Development

No branches or pull requests

4 participants