Skip to content

[DataStore] Optional fields related to another table using @belongsTo directive are throwing errors #1792

@srimalaya

Description

@srimalaya

Describe the bug

This is the schema that I am using:

GraphQL Schema

type Blog @model @auth(rules: [{allow: public}]) {
  id: ID!
  name: String!
  customs: [MyCustomModel]
  notes: [String]
  post: [Post] @hasMany(indexName: "postByBlog", fields: ["id"])
}

type Post @model @auth(rules: [{allow: public}]) {
  id: ID!
  name: String!
  blog_id: ID @index(name: "postByBlog")
  random_id: String @index(name: "byRandom")
  blog: Blog @belongsTo(fields: ["blog_id"])
}

type MyCustomModel {
  id: ID!
  name: String!
  desc: String
  children: [MyNestedModel]
}

type MyNestedModel {
  id: ID!
  nestedName: String!
  notes: [String]
}

I already have this schema running and working perfectly on a test app for Android and JS. Now, I am trying to test DataStore on iOS (Swift + SwiftUI). With the above schema, I am successfully able to query all entries from the Blog table. I am also able to query from the Post table ONLY IF a value for "blog" field exists for all entries inside the Post table on DynamoDB.

The issue (specific to iOS only) arises when:

  1. There is no value for "blog" for a particular entry and that entry is queried or is part of the result from a query.
  2. When I try to create a Post and deliberately leave out "blog" OR set "blog" to nil

I have also tried setting no value or nil for the "random_id" field but that does not cause any issues. Only "blog" field causes issues.

I see this in logs whenever it happens in case of both query and save operations:

Error creating post - DataStoreError: The data couldn’t be read because it is missing.
Recovery suggestion: The data couldn’t be read because it is missing.
Caused by:
valueNotFound(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "elements", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "blog", intValue: nil), CodingKeys(stringValue: "id", intValue: nil)], debugDescription: "Expected String value but found null instead.", underlyingError: nil))

There was an issue with the CLI when specifying "null" value for optional Index fields. However, that issue was fixed in CLI version 8.0.2 and works perfectly on Android.

Here are the queries that I am using:

Query for Blog and Save operation for Post

    func queryItem() {
        var blog: Blog? = nil
        Amplify.DataStore.query(Blog.self) {
            switch $0 {
            case .success(let result):
                print("Items: \(result)")
                blog = result[0]
                createItem(item: blog!)
            case .failure(let error):
                print("Error listing items - \(error)")
            }
        }
    }
    
    func createItem(item: Blog) {
        Amplify.DataStore.save(Post(name: "Test-2")) {
            switch $0 {
            case .success:
                print("Created a new post successfully")
            case .failure(let error):
                print("Error creating post - \(error)")
            }
        }
    }

Steps To Reproduce

Steps to reproduce the behavior:
1. Set up app backend with the provided schema
2. Populate data
4. Populate some entries inside `Post` model without specifying value for blog or set blog = nil
5. See error when creating , updating, or querying any entry with missing blog.

Expected behavior

I should be able to list or update all Posts irrespective of whether or not a value for "blog" exists.

Amplify Framework Version

1.24.0

Amplify Categories

DataStore

Dependency manager

Swift PM

Swift version

5.6

CLI version

8.2.0

Xcode version

13.3.1

Relevant log output

Error creating post - DataStoreError: The data couldn’t be read because it is missing.
Recovery suggestion: The data couldn’t be read because it is missing.
Caused by:
valueNotFound(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "elements", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "blog", intValue: nil), CodingKeys(stringValue: "id", intValue: nil)], debugDescription: "Expected String value but found null instead.", underlyingError: nil))

Is this a regression?

No

Regression additional context

No response

Device

iPhone SE (3rd Generation)

iOS Version

15.4

Specific to simulators

No response

Additional context

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdatastoreIssues related to the DataStore category

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions