I am making a sign up page with 3 providers (Twitter, Facebook and Instagram) using next-auth and prisma with mongoDB. The issue appears when I try to sign up with any of the providers. I think the prisma schema is the problem. Here is the error that I receive:
Invalid `p.account.create()` invocation in
C:\...\node_modules\#next-auth\prisma-adapter\dist\index.js:19:42
16 },
17 updateUser: ({ id, ...data }) => p.user.update({ where: { id }, data }),
18 deleteUser: (id) => p.user.delete({ where: { id } }),
→ 19 linkAccount: (data) => p.account.create({
data: {
provider: 'instagram',
type: 'oauth',
providerAccountId: '62921xxxxxx98535',
access_token: 'IGQVJYdU...',
user_id: 178xxxx,
~~~~~~~
userId: '63e2538xxxx'
}
})
Unknown arg `user_id` in data.user_id for type AccountUncheckedCreateInput. Did you mean `userId`? Available args:
type AccountUncheckedCreateInput {
id?: String
userId: String
type: String
provider: String
providerAccountId: String
}
I have red all the documentations about, chatGPT also didn't help much. The prisma schema looks like this:
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String #id #default(auto()) #map("_id") #db.ObjectId
name String?
email String? #unique
emailVerified DateTime? #map("email_verified")
image String?
accounts Account[]
sessions Session[]
##map("users")
}
model Account {
id String #id #default(auto()) #map("_id") #db.ObjectId
userId String #db.ObjectId
type String
provider String
providerAccountId String #map("provider_account_id")
refresh_token String? #db.String
access_token String? #db.String
expires_at Int?
token_type String?
scope String?
id_token String? #db.String
session_state String?
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
##unique([provider, providerAccountId])
##map("accounts")
}
model Session {
id String #id #default(auto()) #map("_id") #db.ObjectId
sessionToken String #unique #map("session_token")
userId String #db.ObjectId
expires DateTime
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
##map("sessions")
}
model VerificationToken {
identifier String #id #default(auto()) #map("_id") #db.ObjectId
token String #unique
expires DateTime
##unique([identifier, token])
##map("verificationtokens")
}
You are passing user_id parameter while creating an account, but there is no field named user_id in the Account model in your schema file.
If you need to pass user_id while creating an account then you need to define it in the Account model as well.
Related
How can I create multiple NextAuth user account types similiar to Upwork's Client/Freelancer accounts?
I'm building a web application and I want a distinct separation between the type of account a user can create.
I'm starting with the a Prisma adaptation of the main NextAuth Schema (provided by NextAuth) and I want to authenticate with Google OAuth.
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
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 Session {
id String #id #default(cuid())
sessionToken String #unique
userId String
expires DateTime
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String #id #default(cuid())
name String?
email String? #unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}
model VerificationToken {
identifier String
token String #unique
expires DateTime
##unique([identifier, token])
}
In Upwork's setup you can create an account as a "Client", which let's you hire freelancers, or you can create an account as a "Freelancer", which lets you take gigs; both are under the same authentication provider but you can easily switch. The separation or the ability to create two types of accounts under the same Authentication details.
How do I edit the schema to support this?
I am trying to implement a relation querie with Prisma ORM but this error does not allow.
My system consists in a bugtracker, where the user can report bugs. So I'm linking the User with the bugs. When I try to create a new data this error appears: "Unique constraint failed on the constraint: Bug_authorId_key"
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id Int #id #default(autoincrement())
name String
email String #unique
password String
role String #default("User")
bugs Bug[]
teamId Int?
team Team? #relation(fields: [teamId], references: [id])
}
model Team {
id Int #id #default(autoincrement())
name String
users User[]
admins Admin[]
}
model Admin {
id Int #id #default(autoincrement())
name String
email String #unique
password String
role String #default("Admin")
teamId Int?
team Team? #relation(fields: [teamId], references: [id])
}
model Bug {
id Int #id #default(autoincrement())
title String
description String
status String
authorId Int
author User #relation(fields: [authorId], references: [id])
}
const bug = await prisma.bug.create({
data: {
title: req.body.title,
status: req.body.status,
description: req.body.description,
author: {
connect: {id: req.body.authorId}
}
}
})
I am using Prisma, MongoDB and NextAuth in a Next js project (Typescript). I'm trying to pass multiple filters in the where clause, but it returns a null array.
In the app there are 2 pages, one is called My Feed where anyone (even if not logged in) can see everyone's published posts. Second page is called My Drafts, where logged in users can view their unpublished posts, and choose to publish or delete them.
Basically, when a user creates a new post, it has a property - published, which is false by default. I am trying to show these unpublished posts, in the my drafts page of a logged in user.
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
const session = await getSession({ req });
if (!session) {
res.statusCode = 403;
return { props: { drafts: [] } };
}
const drafts = await prisma.post.findMany({
where: {
published: false,
author : {email: session.user?.email}
},
include: {
author: {
select: { name: true },
},
},
});
return {
props: { drafts },
};
};
If I remove the author from the where clause, it returns all unpublished posts from all users. If I remove the published:false or keep both - published and email then I'm getting null array, although session is defined.
Here is my prisma schema : -
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model Post {
id String #id #default(auto()) #map("_id") #db.ObjectId
title String
content String?
published Boolean #default(false)
author User? #relation(fields: [authorId], references: [id])
authorId String?
}
model Account {
id String #id #default(auto()) #map("_id") #db.ObjectId
userId String #map("user_id")
type String
provider String
providerAccountId String #map("provider_account_id")
refresh_token String? #db.String
access_token String? #db.String
expires_at Int?
token_type String?
scope String?
id_token String? #db.String
session_state String?
oauth_token_secret String?
oauth_token String?
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
##unique([provider, providerAccountId])
}
model Session {
id String #id #default(auto()) #map("_id") #db.ObjectId
sessionToken String #unique #map("session_token")
userId String #map("user_id")
expires DateTime
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String #id #default(auto()) #map("_id") #db.ObjectId
name String?
email String? #unique
emailVerified DateTime?
image String?
posts Post[]
accounts Account[]
sessions Session[]
}
model VerificationToken {
id String #id #default(auto()) #map("_id") #db.ObjectId
identifier String
token String #unique
expires DateTime
##unique([identifier, token])
}
I'm trying to authenticate with email using NextAuth, Prisma and Amazon SES.
I got:
"Server Error - TypeError: email.split(...)[0].trim(...).replaceAll is
not a function."
It comes from the validation process in NextAuth /node_modules/next-auth/core/routes/signin.js (58:40) but I don't know why it occurs.
Amazon SES seems to work fine in the console in sending smtp request.
This is my code (very basic):
import NextAuth from 'next-auth';
import EmailProvider from 'next-auth/providers/email';
import { PrismaAdapter } from '#next-auth/prisma-adapter';
import { PrismaClient } from '#prisma/client';
const prisma = new PrismaClient();
export default NextAuth({
providers: [
EmailProvider({
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
maxAge: 10 * 60,
}),
],
adapter: PrismaAdapter(prisma),
});
In prisma:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Home {
id String #id #default(cuid()) // alternatives: #default(uuid()) or #default(autoincrement())
image String?
title String
description String
price Float
guests Int
beds Int
baths Int
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
}
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 Session {
id String #id #default(cuid())
sessionToken String #unique
userId String
expires DateTime
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String #id #default(cuid())
name String?
email String? #unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}
model VerificationToken {
identifier String
token String #unique
expires DateTime
##unique([identifier, token])
}
I added a company property to the User model in my prisma.schema file (The rest of the prisma.schema file is still similar to the one in the documentation: https://next-auth.js.org/adapters/prisma)
model User {
id String #id #default(cuid())
name String?
email String? #unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
company Company?
}
model Company {
id Int #id #default(autoincrement())
companyName String #unique
gender String
firstName String
lastName String
street String
houseNumber Int
postcode Int
city String
country String
countryCode String
callNumber Int
emailAddress String
website String?
socials Json?
companyUser User #relation(fields: [companyUserId], references: [id])
companyUserId String #unique
}
The whole authentification process is working fine even after the change but when I try to select a User from the database it only returns a certain portion of the User namely the id, name, email, emailVerified and image property.
How can I change this behaviour?
const user = await prisma.user.findUnique({
where: {
id: ...
}
})
For sure I could only create the Company model without connecting it to the User model and maybe adding the User's id to it to have an implicit connection, but that's undermining the whole purpose...
you're looking for nested reads, if you want to include the whole company model you should use include with the name of the relation, note that this will return all the fields for that specific relation:
const user = await prisma.user.findUnique({
where: {
id: ...
},
include: {
company: true,
},
})
if you want to return specific relation fields with the whole user you should use select inside include:
const user = await prisma.user.findUnique({
where: {
id: ...
},
include: {
company: {
select : {
firstName: true,
},
},
},
})