amplify-flutter icon indicating copy to clipboard operation
amplify-flutter copied to clipboard

ModelQueries.list fails randomly without any logs

Open harini18 opened this issue 1 year ago • 18 comments

Description

ModelQueries.list response does not return sometimes. I am able to get the right values like 10% of the time, rest of the time there is no reply and no logs to debug this issue.

Categories

  • [ ] Analytics
  • [ ] API (REST)
  • [X] API (GraphQL)
  • [ ] Auth
  • [ ] Authenticator
  • [ ] DataStore
  • [ ] Notifications (Push)
  • [ ] Storage

Steps to Reproduce

My Schema:

 Goal: a
    .model({
      direction: a.enum(["INCREASE", "DECREASE"]),
      from: a.float(),
      to: a.float(),
      vitalId: a.id().required(),
      vital: a.belongsTo("Vital", "vitalId"),
      eventId: a.id().required(),
      event: a.belongsTo("Event", "eventId"),
    })
    .authorization((allow) => [allow.owner()]),
  // Vitals Related
  StandardVital: a
    .model({
      name: a.string(),
      vitals: a.hasMany("Vital", "standardVitalId"),
    })
    .authorization((allow) => [
      allow.authenticated().to(["read"]),
      allow.group("Admin"),
    ]),
  CustomVital: a
    .model({
      name: a.string(),
      vitals: a.hasMany("Vital", "customVitalId"),
    })
    .authorization((allow) => [allow.owner()]),
  Vital: a
    .model({
      standardVitalId: a.id(),
      standardVital: a.belongsTo("StandardVital", "standardVitalId"),
      customVitalId: a.id(),
      customVital: a.belongsTo("CustomVital", "customVitalId"),
      goalId: a.id(),
      goal: a.hasOne("Goal", "vitalId"),
      vitalMeasurementLogs: a.hasMany("VitalMeasurementLog", "vitalId"),
    })
    .authorization((allow) => [allow.owner()]),

My Query:

try {
      final request = ModelQueries.list(
        Goal.classType,
        where: Goal.EVENT.eq(event.id),
      );
      final response = await Amplify.API.query(request: request).response;

      if (response.hasErrors) {
        safePrint('errors: ${response.errors}');
        return [];
      }

      final goals = response.data?.items ?? <Goal?>[];

      return goals;
    } on Exception catch (e) {
      safePrint(e);
      rethrow;
    }

For some reason - I don't get response. When I try to debug, the code does flow through after final response = await Amplify.API.query(request: request).response;. There are no logs in VSCode and there are no exceptions that are thrown.

No Idea what is happening.

I am creating this object using:

// Create Vital
    final newVital = Vital(id: uuid(), standardVital: standardVital);

    final vitalRequest = ModelMutations.create(newVital);
    final vitalResponse =
        await Amplify.API.mutate(request: vitalRequest).response;

    if (vitalResponse.data == null) {
      throw Exception("Goal Creation Failed");
    }

    final newlyCreatedVital = (await Amplify.API
            .query(
                request: ModelQueries.get(
                    Vital.classType, vitalResponse.data!.modelIdentifier))
            .response)
        .data;

    // Create Goal
    final newGoal = Goal(
        id: uuid(),
        event: event,
        direction: goalDirection,
        vital: newlyCreatedVital,
        from: from,
        to: to);
    final request = ModelMutations.create(newGoal);
    final response = await Amplify.API.mutate(request: request).response;

Screenshots

No response

Platforms

  • [x] iOS
  • [ ] Android
  • [ ] Web
  • [ ] macOS
  • [ ] Windows
  • [ ] Linux

Flutter Version

3.24.0

Amplify Flutter Version

2.0.0

Deployment Method

Amplify CLI

Schema

No response

harini18 avatar Aug 22 '24 15:08 harini18

Sorry that you are facing this issue and thanks for reporting it. does it only happen on iOS?

NikaHsn avatar Aug 22 '24 16:08 NikaHsn

Yes in iOS emulator.

harini18 avatar Aug 22 '24 16:08 harini18

thanks for confirming. we will look into this issue and get back to you with any updates.

NikaHsn avatar Aug 22 '24 21:08 NikaHsn

Any updates - we are blocked completely.

harini18 avatar Aug 24 '24 14:08 harini18

@harini18 - This is currently in our backlog of issues to attempt to reproduce.

Was this previously working on iOS?

Jordan-Nelson avatar Aug 26 '24 17:08 Jordan-Nelson

No it never worked.

harini18 avatar Aug 27 '24 02:08 harini18

@harini18 Can you use Flutter dev tools to monitor the network traffic (see: https://docs.flutter.dev/tools/devtools/network) and share a screenshot of the request/response? Do you see the request complete in the dev tools?

Jordan-Nelson avatar Aug 29 '24 19:08 Jordan-Nelson

Create Vitals

Request:

{"variables":{"input":{"id":"c6f037ff-86aa-4e01-8b84-76388a105dce","standardVitalId":"328d85f0-e1e9-4d99-a71c-38351f42e54e"}},"query":"mutation createVital($input: CreateVitalInput!, $condition: ModelVitalConditionInput) { createVital(input: $input, condition: $condition) { id createdAt updatedAt standardVital { id name createdAt updatedAt } standardVitalId customVital { id name createdAt updatedAt owner } customVitalId goal { id direction from to createdAt updatedAt owner } goalId owner } }"} Response: {"data":{"createVital":{"id":"c6f037ff-86aa-4e01-8b84-76388a105dce","createdAt":"2024-08-30T13:29:14.740Z","updatedAt":"2024-08-30T13:29:14.740Z","standardVital":null,"standardVitalId":"328d85f0-e1e9-4d99-a71c-38351f42e54e","customVital":null,"customVitalId":null,"goal":null,"goalId":null,"owner":"4801b350-9091-70f1-1e36-3f4990f754b5"}},"errors":[{"path":["createVital","standardVital","id"],"locations":null,"message":"Cannot return null for non-nullable type: 'ID' within parent 'StandardVital' (/createVital/standardVital/id)"},{"path":["createVital","standardVital","createdAt"],"locations":null,"message":"Cannot return null for non-nullable type: 'AWSDateTime' within parent 'StandardVital' (/createVital/standardVital/createdAt)"},{"path":["createVital","standardVital","updatedAt"],"locations":null,"message":"Cannot return null for non-nullable type: 'AWSDateTime' within parent 'StandardVital' (/createVital/standardVital/updatedAt)"},{"path":["createVital","customVital","id"],"locations":null,"message":"Cannot return null for non-nullable type: 'ID' within parent 'CustomVital' (/createVital/customVital/id)"},{"path":["createVital","customVital","createdAt"],"locations":null,"message":"Cannot return null for non-nullable type: 'AWSDateTime' within parent 'CustomVital' (/createVital/customVital/createdAt)"},{"path":["createVital","customVital","updatedAt"],"locations":null,"message":"Cannot return null for non-nullable type: 'AWSDateTime' within parent 'CustomVital' (/createVital/customVital/updatedAt)"},{"path":["createVital","goal","id"],"locations":null,"message":"Cannot return null for non-nullable type: 'ID' within parent 'Goal' (/createVital/goal/id)"},{"path":["createVital","goal","createdAt"],"locations":null,"message":"Cannot return null for non-nullable type: 'AWSDateTime' within parent 'Goal' (/createVital/goal/createdAt)"},{"path":["createVital","goal","updatedAt"],"locations":null,"message":"Cannot return null for non-nullable type: 'AWSDateTime' within parent 'Goal' (/createVital/goal/updatedAt)"}]}

Get Vital

Request

{"variables":{"id":"c6f037ff-86aa-4e01-8b84-76388a105dce"},"query":"query getVital($id: ID!) { getVital(id: $id) { id createdAt updatedAt standardVital { id name createdAt updatedAt } standardVitalId customVital { id name createdAt updatedAt owner } customVitalId goal { id direction from to createdAt updatedAt owner } goalId owner } }"}

Response {"data":{"getVital":{"id":"c6f037ff-86aa-4e01-8b84-76388a105dce","createdAt":"2024-08-30T13:29:14.740Z","updatedAt":"2024-08-30T13:29:14.740Z","standardVital":{"id":"328d85f0-e1e9-4d99-a71c-38351f42e54e","name":"Body Fat Percentage","createdAt":"2024-08-21T01:16:27.358Z","updatedAt":"2024-08-21T01:16:27.358Z"},"standardVitalId":"328d85f0-e1e9-4d99-a71c-38351f42e54e","customVital":null,"customVitalId":null,"goal":null,"goalId":null,"owner":"4801b350-9091-70f1-1e36-3f4990f754b5"}}}

Create Goal

Request {"variables":{"input":{"id":"84c1a806-82bf-4f39-8c04-73e761402ed9","direction":"DECREASE","from":26.0,"to":20.0,"eventId":"6bab29a4-a120-4b7f-8c0a-e904b4ac30c4"}},"query":"mutation createGoal($input: CreateGoalInput!, $condition: ModelGoalConditionInput) { createGoal(input: $input, condition: $condition) { id direction from to createdAt updatedAt event { id name date createdAt updatedAt owner } eventId owner } }"}

Response {"data":null,"errors":[{"path":null,"locations":[{"line":1,"column":21,"sourceName":null}],"message":"Variable 'input' has coerced Null value for NonNull type 'ID!'"}]}

harini18 avatar Aug 30 '24 13:08 harini18

Thanks for providing that. We will attempt to reproduce.

Jordan-Nelson avatar Aug 30 '24 14:08 Jordan-Nelson

Any updates?

harini18 avatar Sep 03 '24 22:09 harini18

@harini18 we will attempt to reproduce this and will provide updates here as we have them. sorry for the delay and thanks for your patience.

NikaHsn avatar Sep 03 '24 23:09 NikaHsn

Given it is has been 2 weeks, and we are completely blocked, it will be great if you could at least look at my code and see if I am doing anything wrong.

Thanks for your help

harini18 avatar Sep 05 '24 00:09 harini18

@harini18 the provided model is missing event, would you please share the event model. as I didn't have the event model, I tried to reproduce this issue listing goals by vitalId and was not able to reproduce this issue. can you confirm if the created goals in the dynamoDB table have event id?

NikaHsn avatar Sep 05 '24 18:09 NikaHsn

// Event Related

  Event: a
    .model({
      name: a.string(),
      date: a.date(),
      plans: a.hasMany("Plan", "eventId"),
      goals: a.hasMany("Goal", "eventId"),
      owner: a
        .string()
        .authorization((allow) => [allow.owner().to(["read", "delete"])]),
    })
    .authorization((allow) => [allow.owner()]),

I am not even able to create goals. I am getting "message":"Variable 'input' has coerced Null value for NonNull type 'ID!'"

harini18 avatar Sep 06 '24 14:09 harini18

would you please share the full graphql response for creating a goal. do you pass all the required field when creating a goal?

NikaHsn avatar Sep 06 '24 17:09 NikaHsn

Create Goal

Request {"variables":{"input":{"id":"84c1a806-82bf-4f39-8c04-73e761402ed9","direction":"DECREASE","from":26.0,"to":20.0,"eventId":"6bab29a4-a120-4b7f-8c0a-e904b4ac30c4"}},"query":"mutation createGoal($input: CreateGoalInput!, $condition: ModelGoalConditionInput) { createGoal(input: $input, condition: $condition) { id direction from to createdAt updatedAt event { id name date createdAt updatedAt owner } eventId owner } }"}

Response {"data":null,"errors":[{"path":null,"locations":[{"line":1,"column":21,"sourceName":null}],"message":"Variable 'input' has coerced Null value for NonNull type 'ID!'"}]}

harini18 avatar Sep 18 '24 13:09 harini18

// Create Goal final newGoal = Goal( id: uuid(), event: event, direction: goalDirection, vital: newlyCreatedVital, from: from, to: to); final request = ModelMutations.create(newGoal); final response = await Amplify.API.mutate(request: request).response;

harini18 avatar Sep 18 '24 13:09 harini18

Hi @harini18,

It looks like your request to create a Goal does not contain a Vital in the input variable. I suspect that's the reason you're seeing "Variable 'input' has coerced Null value for NonNull type 'ID!'".

final newlyCreatedVital = (await Amplify.API
            .query(
                request: ModelQueries.get(
                    Vital.classType, vitalResponse.data!.modelIdentifier))
            .response)
        .data;

In the above code snippet can you verify the newlyCreatedVital you query has value before creating a Goal with it?

Equartey avatar Sep 19 '24 19:09 Equartey