HI i am sharing my schema please provide suggestion. Whenever i open content page i got this error like sync error occured in this model.
type Message #model #auth(rules: [{allow: public}]) {
id: ID!
content: String!
userID: ID! #index(name: "byUser")
chatroomID: ID
}
type ChatRoom #model #auth(rules: [{allow: public}]) {
id: ID!
newMessages: Int
LastMessage: Message #hasOne
Messages: Message #hasOne
ChatRoomUsers: [User] #manyToMany(relationName: "ChatRoomUser")
}
type User #model #auth(rules: [{allow: public}]) {
id: ID!
name: String!
status: String
imageUri: String
Messages: [Message] #hasMany(indexName: "byUser", fields: ["id"])
chatrooms: [ChatRoom] #manyToMany(relationName: "ChatRoomUser")
}
Related
I am currently experiencing an issue with #belongsTo in connection with #auth when more than one sortKey is inside of the parent element.
The following error comes up when I try to amplify push the schema:
🛑 Invalid #belongsTo on Comments:todo. Provided fields do not match the size of primary key(s) for Todos
Below schema should reproduce the error:
type Todos #model #auth(rules: [{ allow: public }]) {
id: ID!
createdAt: String
number: Int
title: String
description: String
comments: [Comments] #hasMany(indexName: "byComments", fields: ["id"])
baseType: String
#index(
name: "byNumber"
queryField: "todosByNumber"
sortKeyFields: ["number"]
)
#index(
name: "byTitle"
queryField: "todosByTitle"
sortKeyFields: ["title"]
)
#index(
name: "byDescription"
queryField: "todosByDescription"
sortKeyFields: ["description"]
)
}
type Comments #model #auth(rules: [{ allow: public }]) {
id: ID!
todosID: ID! #index(name: "byComments")
todo: Todos #belongsTo(fields: ["todosID"])
createdAt: String
firstName: String
lastName: String
messageID: ID #index(name: "commentsByMessages")
message: Messages #belongsTo(fields: "messageID")
}
type Messages #model #auth(rules: [{ allow: public }]) {
id: ID!
title: String
content: String
comments: [Comments] #hasMany(indexName: "byComments", fields: ["id"])
}
Does anyone have a solution on how to setup #belongsTo and #auth correctly?
Looking forward to your help!
I am constructing a React Native app with AWS Amplify, AppSync, Cognito, Dynamodb and GraphQL.
I designed the schema.graphql file and want to push that to the cloud (amplify push).
Initially, it had no problem pushing to the cloud.
But as soon as I introduced #key and #connection , I get an error when pushing to cloud.
amplify push
The error is:
🛑 An error occurred during the push operation: Your GraphQL Schema is using
"#connection", "#key" directives from an older version of the GraphQL Transformer.
Visit https://docs.amplify.aws/cli/migration/transformer-migration/ to
learn how to migrate your GraphQL schema.
I read the article and followed their instruction to the best of my ability.
Then I get this error when pushing:
🛑 An error occurred during the push operation: Schema validation failed.
Unknown argument "keyName" on directive "#hasMany". Did you mean "indexName"?
GraphQL request:13:44
12 |
13 | portfolioCoins: [PortfolioCoin] #hasMany(keyName: "byUser", fields: ["id"])
| ^
14 | }
Directive "primaryKey" may not be used on OBJECT.
GraphQL request:16:27
15 |
16 | type PortfolioCoin #model #primaryKey(name: "byUser", fields: ["userId"]) {
| ^
17 | id: ID!
Unknown argument "name" on directive "#primaryKey".
GraphQL request:16:39
15 |
16 | type PortfolioCoin #model #primaryKey(name: "byUser", fields: ["userId"]) {
| ^
17 | id: ID!
Unknown argument "fields" on directive "#primaryKey".
GraphQL request:16:55
15 |
16 | type PortfolioCoin #model #primaryKey(name: "byUser", fields: ["userId"]) {
| ^
17 | id: ID!
Unknown argument "fields" on directive "#manyToMany".
GraphQL request:21:26
20 | userId: ID!
21 | user: User #manyToMany(fields: ["userId"])
| ^
22 |
Directive "#manyToMany" argument "relationName" of type "String!" is required, but it was not provided.
GraphQL request:21:14
20 | userId: ID!
21 | user: User #manyToMany(fields: ["userId"])
| ^
22 |
Unknown argument "fields" on directive "#manyToMany".
GraphQL request:24:26
23 | coinId: ID!
24 | coin: Coin #manyToMany(fields: ["coinId"])
| ^
25 | }
Directive "#manyToMany" argument "relationName" of type "String!" is required, but it was not provided.
GraphQL request:24:14
23 | coinId: ID!
24 | coin: Coin #manyToMany(fields: ["coinId"])
| ^
25 | }
This is my schema.graphql file:
# This "input" configures a global authorization rule to enable public access to
# all models in this schema. Learn more about authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules
# input AMPLIFY {
# globalAuthRule: AuthRule = { allow: public }
# } # FOR TESTING ONLY!
type User #model #auth(rules: [{ allow: public }]) {
id: ID!
email: String!
name: String
image: String
networth: Float!
portfolioCoins: [PortfolioCoin] #connection(keyName: "byUser", fields: ["id"])
}
type PortfolioCoin #model #key(name: "byUser", fields: ["userId"]) {
id: ID!
amount: Float!
userId: ID!
user: User #connection(fields: ["userId"])
coinId: ID!
coin: Coin #connection(fields: ["coinId"])
}
type Coin #model {
id: ID!
cgId: String!
name: String!
symbol: String!
image: String
currentPrice: Float!
valueChange24H: Float!
valueChange1D: Float!
valueChange7D: Float!
priceHistoryString: String
}
And here is an image of the table relationships for your reference:
Please tell me how I can replace the #key and #connection properly so that I can amplify push successfully. Your help will be extremely appreciated.
I encountered this a while back when GraphQL Transformer version 2 came out and my schema stopped working.
I found this article helpful to understand how the new keywords worked.
https://aws.amazon.com/blogs/mobile/aws-amplify-announces-the-new-graphql-transformer-v2-more-feature-rich-flexible-and-extensible/
This link is also very helpful for modeling in the current version: https://docs.amplify.aws/cli/graphql/data-modeling
I think your schema should probably work as follows in the current version:
type User #model #auth(rules: [{ allow: public }]) {
id: ID!
email: String!
name: String
image: String
networth: Float!
portfolioCoins: [PortfolioCoin] #hasMany
}
type PortfolioCoin #model #key(name: "byUser", fields: ["userId"]) {
id: ID!
amount: Float!
user: User #belongsTo
coin: Coin #hasOne
}
type Coin #model {
id: ID!
cgId: String!
name: String!
symbol: String!
image: String
currentPrice: Float!
valueChange24H: Float!
valueChange1D: Float!
valueChange7D: Float!
priceHistoryString: String
}
With the GraphQL Transformer v2, Amplify introduces as a range of new features to help customers create app backends even faster and easier.
The #key directive is being replaced by two new directives.
#primaryKey and #index
#connection is being replaced with several new directives.
#hasOne
#hasMany
#belongsTo
#manyToMany
for your case is #hasOne
read
https://docs.amplify.aws/cli/migration/transformer-migration/#changes-that-amplify-cli-will-auto-migrate-for-you
for more info on this.
Here's your code let me know if bugs arise.
type User #model #auth(rules: [{ allow: public }]) {
id: ID!
email: String!
name: String
image: String
networth: Float!
portfolioCoins: PortfolioCoin #hasOne(keyName: fields: ["id"])
}
type PortfolioCoin #model {
id: ID!
amount: Float!
userId: ID!#primaryKey #index(name:"byUser")
user: User #hasOne(fields: ["userId"])
coinId: ID!
coin: Coin #hasOne(fields: ["coinId"])
}
type Coin #model {
id: ID!
cgId: String!
name: String!
symbol: String!
image: String
currentPrice: Float!
valueChange24H: Float!
valueChange1D: Float!
valueChange7D: Float!
priceHistoryString: String
}
My issue is that I need to have a connection between two schema models where each links to an array of the other. The scenario here is I have multiple Location, each Location has multiple Staff. Each Staff can also have multiple Location that they are authorized at.
I don't see a way to do this in the documentation. Originally I have each Location with multiple Staff, but this limits each Staff to 1 Location. I'm toying with the idea of altLocationNames as an array of strings with each Staff, but this would require me to perform an extra query of all Staff or all Locations if the altLocationNames is needed.
Does anybody know a clever way to do this, or even just the best way for me to get all Staff at Location as well as all Locations for a specific Staff?
Schemas:
type Staff
#model
#auth(rules: [{ allow: private, provider: iam }, { allow: private, provider: userPools }])
#key(fields: ["email"])
#key(name: "byId", fields: ["id"], queryField: "listStaffsById")
#key(name: "byLocation", fields: ["locationName", "recordedAt"], queryField: "listStaffsByLocation")
#key(name: "byRole", fields: ["role", "recordedAt"], queryField: "listStaffsByRole")
#key(name: "byStatus", fields: ["status", "recordedAt"], queryField: "listStaffsByStatus") {
email: AWSEmail!
altEmails: [AWSEmail]
id: ID!
locationName: String!
location: Location #connection(fields: ["locationName"])
altLocationNames: [String]
firstName: String
lastName: String
role: StaffRole
status: StaffStatus
recordedAt: AWSDateTime!
createdAt: AWSDateTime!
updatedAt: AWSDateTime!
}
type Location
#model
#auth(rules: [{ allow: private, provider: iam }, { allow: private, provider: userPools }])
#key(fields: ["name"]) {
name: String!
subdomain: String
address: String
phone: String
email: AWSEmail
staff: [Staff] #connection(keyName: "byLocation", fields: ["name"])
createdAt: AWSDateTime!
updatedAt: AWSDateTime!
}
Can you create middle table between location and staff table and fetch via that table.
Example:
type Staff
#model {
id: ID!
name: String
locations: [StaffLocation] #connection(keyName: "staffLocationByStaffId", fields: ["id"])
}
type Location
#model {
id: ID!
name: String
staffs: [StaffLocation] #connection(keyName: "staffLocationByLocationId", fields: ["id"])
}
type StaffLocation
#key(name: "staffLocationByStaffId", fields: ["staffId"])
#key(name: "staffLocationByLocationId", fields: ["locationId"])
#model {
id: ID!
staffId: ID!
locationId: ID!
staff: Staff #connection(fields: ["staffId"])
location: Location #connection(fields: ["locationId"])
}
type StudentCourses
#model(queries: null)
#auth(rules: [{ allow: public }])
#key(name: "byStudent", fields: ["studentID", "courseID"])
#key(name: "byCourse", fields: ["courseID", "studentID"]) {
id: ID!
studentID: ID!
courseID: ID!
student: Student! #connection(fields: ["studentID"])
course: Course! #connection(fields: ["courseID"])
}
type Course
#model
#auth(rules: [{ allow: public }])
#key(name: "bySchool", fields: ["schoolID"]) {
id: ID!
courseName: String!
schoolID: ID!
students: [Student!] #connection(keyName: "byCourse", fields: ["id"])
}
type Student
#model
#auth(rules: [{ allow: public }])
#key(name: "bySchool", fields: ["schoolID"]) {
id: ID!
studentName: String
studentEmail: String
sisID: Int
schoolID: ID!
courses: [Course!] #connection(keyName: "byStudent", fields: ["id"])
}
I followed the steps in docs to create a many to many relationship between student and courses but i keep getting this error Key byCourse does not exist for model Student even thought i created a model to connect school and courses. Thanks in advance
You need to omit keyName from Course, since in Student model, you have list of courses, so you can't really have #key directive for that.
https://docs.amplify.aws/cli-legacy/graphql-transformer/connection/#many-to-many-connections
type Course
#model
#auth(rules: [{ allow: public }])
#key(name: "bySchool", fields: ["schoolID"]) {
id: ID!
courseName: String!
schoolID: ID!
students: [Student!] #connection(fields: ["id"])
}
Anyone who is upto V2 of Amplify, they can get guidance from this link
https://docs.amplify.aws/cli/graphql/data-modeling/#belongs-to-relationship
Updated Flow has the following changes
You need to add #manyToMany on both tables that are going to join
This will create a third table by itself and will add Queries and Mutations for it as well.
I'm trying to push my AWS Amplify API schema/create the resource but it errors out saying:
✖ An error occurred when pushing the resources to the cloud
managerId field is not of type Int
The error goes away if I change managerId to an Int on the Writer type but I don't want to do that. It should be an ID. Any idea what's wrong here?
schema.graphql
type Writer implements Person
#model
#searchable
#key(name: "byManager", fields: ["managerId", "hourlyPay"])
#auth(rules: [
{allow: groups, groups: ["Admin"]},
{allow: public, provider: iam, operations: [read]}
])
{
id: ID!
managerId: ID!
name: String!
hourlyPay: Float!
manager: Manager! #connection(fields: ["managerId"])
}
type Manager implements Person
#model
#searchable
#auth(rules: [
{allow: groups, groups: ["Admin"]},
{allow: public, provider: iam, operations: [read]}
])
{
id: ID!
name: String!
department: String
writers: [Writer!]! #connection(keyName: "byManager", fields: ["id"])
}
Thanks!
I had the same issue in an Android project I was working on.
I fixed it by placing the next code in a file I created under app/src/main/graphql (I had to create the folder graphql).
/app/src/main/graphql/aws-directives.graphql
directive #connection(name: String, keyField: String, sortField: String, limit: Int) on FIELD_DEFINITION
Then, instead of using #key I only used the directive #connection like this
type Comment #model {
id: ID!
text: String!
postId: Post #connection(name: "commentsByPost")
}
type Post #model {
id: ID!
comments: [Comment] #connection(name: "commentsByPost")
}
Finally when you create comments you have to pass the postId. If you do a query to list the Posts and its comments you will get the comments associated with each post correctly.