Skip to content

Android's mutation selection set is incompatible with iOS' subscription handling #995

@jamesonwilliams

Description

@jamesonwilliams

From @Amplifiyer:

While testing the sync between local and remote, @jamesonwilliams and I found some weird behavior between how it works in iOS and Android. The selection set of the create mutations in iOS seem to include the full nested model fields, while in android it’s only the ID. So for instance if I create two mutations from AppSync as follows:

mutation OnlyIdMutation {
  createPost(input: {blogID: "6a83a3b4-2b82-4dfa-8b58-5e32326865a2", rating: 10, title: "Remote blog 6"}) {
    _deleted
    _lastChangedAt
    _version
    blogID
    created
    createdAt
    id
    rating
    title
    updatedAt
    blog {
      id
    }
  }
}

and

mutation FullNestedModelMutation {
  createPost(input: {blogID: "6a83a3b4-2b82-4dfa-8b58-5e32326865a2", rating: 10, title: "Remote blog 6"}) {
    _deleted
    _lastChangedAt
    _version
    blogID
    created
    createdAt
    id
    rating
    title
    updatedAt
    blog {
      id
      updatedAt
      name
      createdAt
      _version
      _lastChangedAt
      _deleted
    }
  }
}

Both are successful on Android, but only the later works on iOS. The first one will result in some GraphQL errors on the iOS client:

{
  "id": "2ACF986E-7607-4CD7-AEE3-148F34B01183",
  "type": "data",
  "payload": {
    "data": {
      "onCreatePost": {
        "id": "909fccc6-7ad3-4408-8b49-23616123413e",
        "created": null,
        "rating": 3,
        "title": "Post 2 android\t",
        "blog": null,
        "__typename": "Post",
        "_version": 1,
        "_deleted": null,
        "_lastChangedAt": 1606251462643
      }
    },
    "errors": [
      {
        "message": "Cannot return null for non-nullable type: 'String' within parent 'Blog' (/onCreatePost/blog/name)",
        "path": [
          "onCreatePost",
          "blog",
          "name"
        ]
      },
      {
        "message": "Cannot return null for non-nullable type: 'Int' within parent 'Blog' (/onCreatePost/blog/_version)",
        "path": [
          "onCreatePost",
          "blog",
          "_version"
        ]
      },
      {
        "message": "Cannot return null for non-nullable type: 'AWSTimestamp' within parent 'Blog' (/onCreatePost/blog/_lastChangedAt)",
        "path": [
          "onCreatePost",
          "blog",
          "_lastChangedAt"
        ]
      }
    ]
  }
}

@jamesonwilliams notes: We have a toggle for this behavior, when making GraphQL requests. The DataStore category only includes requests IDs from children, and the API category requests all fields.

@jamesonwilliams & @richardmcclellan are not aware of any good reason why it needs to be this way.


@drochetti notes: It’s breaking in iOS most likely because the underlying model is required or has required properties. Swift is very strict when deserializing JSON since types declared as required must be provided at creation time. You can’t do name: String! and then not provide it when constructing the object.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdatastoreDataStore category/pluginsflutterCalling Amplify Android via the Flutter facade

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions