aws-amplify / amplify-flutter

A declarative library with an easy-to-use interface for building Flutter applications on AWS.
https://docs.amplify.aws
Apache License 2.0
1.32k stars 248 forks source link

GraphQL AppSync Subscription Sync error "GraphQLResponse.Error{message='Cannot return null for non-nullable" #4376

Closed rmazur closed 8 months ago

rmazur commented 9 months ago

Description

When subscribing to observeQuery function provided by the Amplify DataStore plugin with the following code:

Amplify.DataStore.observeQuery<BPFeedback>(
      BPFeedback.classType,
      where: BPFeedback.USERTOID
          .eq(AuthService.instance.loggedInUser!.id)
          .and(BPFeedback.ISDRAFT.eq(false))
          .and(BPFeedback.READ.eq(false)),
      sortBy: [BPFeedback.DATETIMESENT.descending()],
    )

we are getting this error:
amplify_error2.log.txt when new feedback is created for user.

When calling the createBPFeedback GraphQL API from the AWS AppSync console.

Screenshot 2024-01-23 at 8 35 39 PM

with all response value selected is working fine and the observeQuery recieve the feedback without any issue.

But When calling the createBPFeedback GraphQL API from the AWS AppSync console with some of the response values not selected (like createdAt, updatedAt, _lastUpdatedAt) we are getting this error amplify_erro4.log.txt and then all the feedbacks sent using the app have the same error as this one.

We have tried testing the observeQuery function in a simple TodoApp and it also had similar issue but we resolved it by adding conflict resolution to the models. And then it working fine. I tried the same fix but that didn't work for this project.

Question 1: Why is the AWS AppSync console query affecting the error being received on the app?

Question 2: What might be the cause of such as error?

Categories

Steps to Reproduce

Code: Amplify.DataStore.observeQuery(       BPFeedback.classType,       where: BPFeedback.USERTOID           .eq(AuthService.instance.loggedInUser!.id)           .and(BPFeedback.ISDRAFT.eq(false))           .and(BPFeedback.READ.eq(false)),       sortBy: [BPFeedback.DATETIMESENT.descending()],     )

Screenshots

image

Platforms

Flutter Version

3.16.9

Amplify Flutter Version

1.6.1

Deployment Method

Amplify CLI

Schema

enum BpValOrExp {
  VALUE
  EXPECTATION
}

type BPFeedback @aws_lambda @model @auth(rules: [{allow: custom}]) {
  id: ID!
  description: String
  anonymousMsg: Boolean
  dateTimeSent: AWSDateTime
  read: Boolean
  isDraft: Boolean
  draftPageRoute: String
  rating: Float
  bpValueID: ID @index(name: "byBPFeedbackValue")
  bpValue: BPValueOrExpectation @belongsTo(fields: ["bpValueID"])
  bpBehaviourID: ID @index(name: "byBPFeedbackBehaviour")
  bpBehaviour: BPBehaviour @belongsTo(fields: ["bpBehaviourID"])
  userFromID: ID! @index(name: "byUserFrom", sortKeyFields: ["description"])
  userToID: ID @index(name: "byUserTo", sortKeyFields: ["description"])
}

type BPBehaviour @aws_lambda @model @auth(rules: [{allow: custom}]) {
  id: ID!
  behaviour: String!
  bpvalueID: ID @index(name: "byBPValueOrExpectation")
  sortOrder: Int
  feedbacks: [BPFeedback] @hasMany(indexName: "byBPFeedbackBehaviour", fields: ["id"])
}

type BPValueOrExpectation @aws_lambda @model @auth(rules: [{allow: custom}]) {
  id: ID!
  name: String!
  bpBehaviour: [BPBehaviour] @hasMany(indexName: "byBPValueOrExpectation", fields: ["id"])
  valueOrExpectation: BpValOrExp
  sortOrder: Int
  feedbacks: [BPFeedback] @hasMany(indexName: "byBPFeedbackValue", fields: ["id"])
}

type User @aws_lambda @model @auth(rules: [{allow: custom}]) {
  id: ID!
  name: String!
  ntid: String!
  email: String
  canReceiveFeedback: Boolean!
  feedbackFrom: [BPFeedback] @hasMany(indexName: "byUserFrom", fields: ["id"])
  feedbackTo: [BPFeedback] @hasMany(indexName: "byUserTo", fields: ["id"])
}

type Article @aws_lambda @model @auth(rules: [{allow: custom}]) {
  id: ID!
  title: String!
  s3ImageFile: String
  description: String
  ctaText: String
  content: String
  s3TargetIdentity: String
  sortOrder: Int
}

type UserDevice @aws_lambda @model @auth(rules: [{allow: custom}]) {
  id: ID!
  ntId: String!
  deviceToken: String!
}
NikaHsn commented 9 months ago

Sorry that you are facing this issue and thanks for reporting it. We will look into this and get back to you when we have updates.

NikaHsn commented 9 months ago

@rmazur createdAt and updatedAt date fields are required for Datastore sync and also for decoding AppSync requests into Dart models. you can look at generated dart models to see the fields marked as required.

Why is the AWS AppSync console query affecting the error being received on the app?

When calling the createBPFeedback GraphQL API from the AWS AppSync console with createdAt and updatedAt being null DataStore sync fails as these field are required.

What might be the cause of such as error?

looking at the error logs seems that createdAt and updatedAtare missing onCreateUserDevice.

NikaHsn commented 8 months ago

@rmazur I'm going to close this issue as we didn't hear back from you. I hope the previous response was helpful and feel free to respond if you have furture question.