Skip to content

Why don't I get any nested @hasMany array?

0

Hi! I am having some trouble with querying some of my models using GraphQl for my Swift application. I have made a schema.graphql file and set up api and auth using the aws amplify cli. but when I try to query some data from my database I don't get it, or it does not seem to exist for that model. but when I try to get it from another place it works fine.

Here is my schema.graphql file

input AMPLIFY { globalAuthRule: AuthRule = { allow: public } } # FOR TESTING ONLY!

type CommunityUser @model {
  id: ID!
  username: String!
  name: String!
  profilePicture: String
  createdCommunities: [Community] @hasMany(indexName: "byCreatedBy", fields: ["id"])
  adminCommunities: [Community] @hasMany(indexName: "byAdmin", fields: ["id"])
  posts: [CommunityPost] @hasMany(indexName: "byUser", fields: ["id"])
  comments: [CommunityPostComment] @hasMany(indexName: "byUser", fields: ["id"])
  memberOfCommunities: [CommunityUserCommunity] @hasMany(indexName: "byCommunityUser", fields: ["id"])
  likedPosts: [CommunityPostLike] @hasMany(indexName: "byCommunityUser", fields: ["id"]) # New field for liked posts
  repostedPosts: [CommunityPostRepost] @hasMany(indexName: "byCommunityUser", fields: ["id"]) # New field for reposted posts
  bookmarkedPosts: [Bookmark] @hasMany(indexName: "byCommunityUser", fields: ["id"]) # New field for bookmarked posts
  likedComments: [CommunityPostCommentLike] @hasMany(indexName: "byCommunityUser", fields: ["id"]) # New field for liked comments
  repostedComments: [CommunityPostCommentRepost] @hasMany(indexName: "byCommunityUser", fields: ["id"]) # New field for reposted comments
}

type Community @model @auth(rules: [{ allow: public }]) {
  id: ID! 
  photo: String!
  name: String!
  description: String!
  rules: [String!]!
  newsString: String!
  stockSymbol: String!
  category: String! # Adding category field
  createdBy: CommunityUser @belongsTo(fields: ["createdById"])
  createdById: ID! @index(name: "byCreatedBy")
  admin: CommunityUser @belongsTo(fields: ["adminId"])
  adminId: ID! @index(name: "byAdmin")
  members: [CommunityUserCommunity] @hasMany(indexName: "byCommunity", fields: ["id"])
  forums: [Forum] @hasMany(indexName: "byCommunity", fields: ["id"]) # Adding forums field
  posts: [CommunityPost] @hasMany(indexName: "byCommunity", fields: ["id"]) # Adding posts field
}

type Forum @model {
  id: ID!
  name: String!
  description: String!
  community: Community @belongsTo(fields: ["communityId"])
  communityId: ID! @index(name: "byCommunity")
  posts: [CommunityPost] @hasMany(indexName: "byForum", fields: ["id"]) # Posts within a forum
}

type CommunityPost @model {
  id: ID!
  user: CommunityUser @belongsTo(fields: ["userId"])
  userId: ID! @index(name: "byUser")
  content: String!
  community: Community @belongsTo(fields: ["communityId"]) # Direct relationship with Community
  communityId: ID! @index(name: "byCommunity")
  forum: Forum @belongsTo(fields: ["forumId"])
  forumId: ID! @index(name: "byForum")
  comments: [CommunityPostComment] @hasMany(indexName: "byPost", fields: ["id"])
  likes: [CommunityPostLike] @hasMany(indexName: "byPost", fields: ["id"]) # New field for likes
  reposts: [CommunityPostRepost] @hasMany(indexName: "byPost", fields: ["id"]) # New field for reposts
  viewCount: Int! # New field for view counter
  bookmarks: [Bookmark] @hasMany(indexName: "byPost", fields: ["id"]) # Added field for bookmark
}

type CommunityPostComment @model {
  id: ID!
  user: CommunityUser @belongsTo(fields: ["userId"])
  userId: ID! @index(name: "byUser")
  content: String!
  post: CommunityPost @belongsTo(fields: ["postId"])
  postId: ID! @index(name: "byPost")
  parentCommentId: ID @index(name: "byParentComment") # Field for parent comment ID
  comments: [CommunityPostComment] @hasMany(indexName: "byParentComment", fields: ["id"]) # Child comments
  likes: [CommunityPostCommentLike] @hasMany(indexName: "byComment", fields: ["id"]) # New field for likes
  reposts: [CommunityPostCommentRepost] @hasMany(indexName: "byComment", fields: ["id"]) # New field for reposts
  viewCount: Int! # New field for view counter
}

# Join table for many-to-many relationship between CommunityUser and Community
type CommunityUserCommunity @model {
  id: ID!
  communityUser: CommunityUser @belongsTo(fields: ["communityUserId"])
  communityUserId: ID! @index(name: "byCommunityUser")
  community: Community @belongsTo(fields: ["communityId"])
  communityId: ID! @index(name: "byCommunity")
}

# Join table for many-to-many relationship between CommunityPost and CommunityUser for likes
type CommunityPostLike @model {
  id: ID!
  communityUser: CommunityUser @belongsTo(fields: ["communityUserId"])
  communityUserId: ID! @index(name: "byCommunityUser")
  post: CommunityPost @belongsTo(fields: ["postId"])
  postId: ID! @index(name: "byPost")
}

# Join table for many-to-many relationship between CommunityPost and CommunityUser for reposts
type CommunityPostRepost @model {
  id: ID!
  communityUser: CommunityUser @belongsTo(fields: ["communityUserId"])
  communityUserId: ID! @index(name: "byCommunityUser")
  post: CommunityPost @belongsTo(fields: ["postId"])
  postId: ID! @index(name: "byPost")
}

# Join table for many-to-many relationship between CommunityUser and CommunityPost for bookmark
type Bookmark @model {
  id: ID!
  communityUser: CommunityUser @belongsTo(fields: ["communityUserId"])
  communityUserId: ID! @index(name: "byCommunityUser")
  post: CommunityPost @belongsTo(fields: ["postId"])
  postId: ID! @index(name: "byPost")
}

# Join table for many-to-many relationship between CommunityPostComment and CommunityUser for likes
type CommunityPostCommentLike @model {
  id: ID!
  communityUser: CommunityUser @belongsTo(fields: ["communityUserId"])
  communityUserId: ID! @index(name: "byCommunityUser")
  comment: CommunityPostComment @belongsTo(fields: ["commentId"])
  commentId: ID! @index(name: "byComment")
}

# Join table for many-to-many relationship between CommunityPostComment and CommunityUser for reposts
type CommunityPostCommentRepost @model {
  id: ID!
  communityUser: CommunityUser @belongsTo(fields: ["communityUserId"])
  communityUserId: ID! @index(name: "byCommunityUser")
  comment: CommunityPostComment @belongsTo(fields: ["commentId"])
  commentId: ID! @index(name: "byComment")
}

The problem is when I try to get a CommunityPost and the list likes, there is nothing there, but when I try to get CommunityUser and the list likedPosts it works just fine and gives me the CommunityPostLike. And I could swear it is done the same way for both of them. The problem is at least also for bookmarks but it might be elsewhere as well. Is there something wrong with how I have the schema set up or what is the issue here?

1 Answer
0

Hello Kristoffer Melen, thank you for sharing your code and the challenges you're having with querying nested @hasMany relationships in your GraphQL schema for your Swift application using AWS Amplify. This is a common challenge when working with complex data models. (NOTE: Remember to always follow security best practices, such as implementing proper authentication and authorization in your app, and using the principle of least privilege when setting up API permissions.). Let's address this step by step:

Schema Definition: Ensure your schema.graphql file correctly defines the @hasMany relationship between your models. For example:

type Parent @model {
      id: ID!
      children: [Child] @hasMany
    }

    type Child @model {
      id: ID!
      parent: Parent @belongsTo
    }

Query Structure: When querying, make sure you're explicitly requesting the nested fields. For example:

query GetParent {
      getParent(id: "parentId") {
        id
        children {
          items {
            id
            // other child fields
          }
        }
      }
    }

API Configuration: Verify that your API is correctly configured in your Amplify setup. You can check this in your amplifyconfiguration.json file.

Code Implementation: In your Swift code, ensure you're using the correct query and handling the nested data properly. For example:

Amplify.API.query(request: .get(Parent.self, byId: "parentId")) { result in
      switch result {
      case .success(let parent):
        if let children = parent.children {
          // Process children
        }
      case .failure(let error):
        print("Error: \(error)")
      }
    }

Data Synchronization: If you've recently updated your schema, make sure to run amplify push to synchronize your local changes with the cloud.

Permissions: Check if you have the necessary permissions set up in your API to allow querying of nested relationships.

Pagination: Be aware that @hasMany relationships are paginated by default. You might need to implement pagination in your queries to retrieve all related items.

Debugging: Use AWS AppSync console to test your queries directly and compare the results with what you're getting in your app.

If you're still facing issues after checking these points, I recommend:

  1. Double-checking your schema definitions and relationships.
  2. Verifying your query structure in the AppSync console.
  3. Reviewing the Amplify documentation for any recent changes or known issues.
  4. If the problem persists, consider opening a support case with AWS Support for more targeted assistance.

Additional Resources:

New for AWS Amplify – Query MySQL and PostgreSQL database for AWS CDK | AWS News Blog

Hopefully this helps get you closer to a resolution.

Best wishes and thank you for using AWS!

Brian

AWS
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.