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

Updating model attribute using Amplify.API.Query

Open ip5038 opened this issue 1 year ago • 3 comments
trafficstars

Describe the bug

I'm fetching a model via Amplify.API.query and updating one of the model attributes. Then I'm saving that model again, but it doesn't update the attribute.

Here is what happens Mutation is triggered by user clicking on a button. On each click Amplify.Datastore.save(theModel) is called.

  1. First click does nothing
  2. Second click updates the _version but not the attribute.
  3. Third click updates the version and the attribute (as expected).

The model I am trying to do this on has secondary index, but I also have another model (which doesn't have secondary index) and it doesn't work either. I update both models in the same way, but no luck.

I am not comfortable sharing the schema. So here is a sample schema with the same structure and GSI setup

enum MyEnum { Enum_Val_A Enum_Val_B Enum_Val_C Enum_Val_D }

type MyModel @model @auth(rules: [{allow: public}]) { id: ID! attribute_A: ID! @index(name: "myGSI", sortKeyFields: ["attribute_C"], queryField: "myQueryField") attribute_B: ID! attribute_C: MyEnum attribute_D: ID }

What I have tried to fix I have conflict resolution enabled . I tried auto-merge, optimistic, and disabled the conflict resolution but same issue each time.

Steps To Reproduce

Steps to reproduce the behavior:
I am going to assume you have the models and backend setup, so I will only list the swift code execution needed.

!!!!! NOTE !!!!!!
This only happens if I clear the datastore before clicking the button. I need to clear datastore when new user logs in.

Before getting started 
1. Clear the amplify datastore (each time you restart the app).

Setup a button to trigger these steps each time its clicked:
2. Query the model by Id using Amplify.API.Query
3. Update one of the model attributes
4. Save that model via Amplify.Datastore.save()


Here is the code for the steps above
_update via DataStore_

 var model = Amplify.API.query(MyModel.self, byId: "the_id")
 model.attribute_C = ENUM_VAL_B; // This is new value for enum. 
 Amplify.DataStore.save(model)

I also tried using Amplify.API.mutate instead of datastore, but it did not work.
_update via API mutate_

 var model = Amplify.API.query(MyModel.self, byId: "the_id")
 model.attribute_C = ENUM_VAL_B; // This is new value for enum. 
 Amplify.API.mutate(model)

Expected behavior

The attribute on the model fetched via Amplify.API.query should be updated on first try.

Amplify Framework Version

12.6.0

Amplify Categories

API, DataStore

Dependency manager

Cocoapods

Swift version

6.9.2

CLI version

12.6.0

Xcode version

Version 15.2 (15C500b)

Relevant log output

No response

Is this a regression?

No

Regression additional context

No response

Platforms

iOS

OS Version

iOS 17.0

Device

iPhone 15 Pro Simulator

Specific to simulators

No. It happens on real device as well.

Additional context

No response

ip5038 avatar Feb 16 '24 00:02 ip5038

@ip5038 Thanks for raising the issue. Our team will look into the issue and provide an update as soon as we can.

harsh62 avatar Feb 16 '24 21:02 harsh62

I wasn't able to find the fix for this issue, but the workaround to this is using a custom lambda conflict resolver. Add a custom lambda resolver via amplify cli and you can configure how you want to deal with conflicts. In my case, I just resolved the conflict without doing checks for versions or anything.

Amplify docs has information on how to setup custom lambda resolver. This will also come in handy if you want to learn more about conflict resolutions including custom lambda resolutions: https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html

ip5038 avatar Mar 01 '24 17:03 ip5038

Hello, Do you know the Amplify version being used? Latest version is 2.27.2 https://github.com/aws-amplify/amplify-swift/releases/tag/2.27.2

When you save the model after the update, are you seeing any errors being logged into the console? Are you able to receive .syncQueriesReady and .ready Datastore event? https://docs.amplify.aws/react/build-a-backend/more-features/datastore/datastore-events/#syncqueriesready

You can use Amplify.Logging.logLevel = .verbose to enable verbose logging

It'd be great if you could attach the logs in the issue after removing sensitive information.

thisisabhash avatar Mar 13 '24 22:03 thisisabhash

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

github-actions[bot] avatar Jul 23 '24 21:07 github-actions[bot]