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.33k stars 247 forks source link

Can't save One to Many Models Using Data Store #1442

Closed irisk29 closed 2 years ago

irisk29 commented 2 years ago

Description

Hello, I'm trying to save via Data Store Product that is connected to Store (one Store has many Products). The store is saved successfully (I can see it in the content section in AWS amplify studio) but not the product. I have tried in many ways -

  1. first save the product than the store
  2. first save the store then the product
  3. save just the product without/with the store id

but nothing works, I could never see the product in the content section.

Categories

Steps to Reproduce

the schema is:

type ProductModel @model @auth(rules: [{allow: public}]) {
  id: ID!
  name: String
  categories: AWSJSON
  price: Float
  imageUrl: String
  description: String
  onlinestoremodelID: ID @index(name: "byOnlineStoreModel")
  shoppingbagmodelID: ID @index(name: "byShoppingBagModel")
}

type OnlineStoreModel @model @auth(rules: [{allow: public}]) {
  id: ID!
  name: String!
  phoneNumber: AWSPhone!
  address: String!
  operationHours: AWSJSON!
  categories: AWSJSON!
  productModel: [ProductModel] @hasMany(indexName: "byOnlineStoreModel", fields: ["id"])
}

This is the code that I'm performing:

OnlineStoreModel o = OnlineStoreModel(
        name: "store test",
        phoneNumber: <phone number>,
        address: <address>,
        operationHours: jsonEncode(["Default"]),
        categories: jsonEncode(["Default"]),
        productModel: []);
    ProductModel p =
        ProductModel(name: "prod", onlinestoremodelID: o.id);
await Amplify.DataStore.save(p);
await Amplify.DataStore.save(o);

Screenshots

Screen Shot 2022-03-08 at 12 27 11 Screen Shot 2022-03-08 at 12 26 24

Platforms

Environment

[✓] Flutter (Channel stable, 2.10.3, on macOS 11.6.1 20G224 darwin-x64, locale en-IL)
[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.

[✓] Xcode - develop for iOS and macOS (Xcode 13.1)
[✓] Chrome - develop for the web
[!] Android Studio (not installed)
[✓] IntelliJ IDEA Ultimate Edition (version 2021.2.3)
[✓] VS Code (version 1.64.2)
[✓] VS Code (version 1.62.3)
[✓] Connected device (2 available)
[✓] HTTP Host Availability

Dependencies

Dart SDK 2.16.1
Flutter SDK 2.10.3
dependencies:
- address_search_field 4.0.1 [flutter flutter_web_plugins http google_maps_flutter]
- amplify_api 0.4.1 [amplify_api_plugin_interface amplify_core collection flutter meta plugin_platform_interface]
- amplify_auth_cognito 0.4.1 [flutter amplify_auth_plugin_interface amplify_core collection plugin_platform_interface]
- amplify_datastore 0.4.1 [flutter amplify_datastore_plugin_interface amplify_core plugin_platform_interface meta collection async]
- amplify_flutter 0.4.1 [amplify_analytics_plugin_interface amplify_api_plugin_interface amplify_auth_plugin_interface amplify_core amplify_datastore_plugin_interface amplify_storage_plugin_interface collection flutter json_annotation meta plugin_platform_interface]
- amplify_storage_s3 0.4.1 [flutter amplify_storage_plugin_interface plugin_platform_interface amplify_core]
- animated_splash_screen 1.2.0 [flutter page_transition]
- cupertino_icons 1.0.4
- flutter 0.0.0 [characters collection material_color_utilities meta typed_data vector_math sky_engine]
- flutter_signin_button 2.0.0 [flutter font_awesome_flutter]
- geolocator 8.2.0 [flutter geolocator_platform_interface geolocator_android geolocator_apple geolocator_web geolocator_windows]
- google_geocoding 0.2.0 [flutter http]
- google_maps_flutter 2.1.1 [flutter flutter_plugin_android_lifecycle google_maps_flutter_platform_interface]
- http 0.13.4 [async http_parser meta path]
- im_stepper 0.1.3 [flutter]
- image_picker 0.8.4+10 [flutter flutter_plugin_android_lifecycle image_picker_for_web image_picker_platform_interface]
- intl 0.17.0 [clock path]
- location 4.3.0 [flutter location_platform_interface location_web]
- material_floating_search_bar 0.3.7 [flutter meta]
- path 1.8.0
- path_provider 2.0.9 [flutter path_provider_android path_provider_ios path_provider_linux path_provider_macos path_provider_platform_interface path_provider_windows]
- permission_handler 9.2.0 [flutter meta permission_handler_android permission_handler_apple permission_handler_windows permission_handler_platform_interface]
- provider 6.0.2 [collection flutter nested]
- qr_code_scanner 0.5.2 [js flutter flutter_web_plugins]
- qr_flutter 4.0.0 [flutter qr]
- shared_preferences 2.0.13 [flutter shared_preferences_android shared_preferences_ios shared_preferences_linux shared_preferences_macos shared_preferences_platform_interface shared_preferences_web shared_preferences_windows]
- sqflite 2.0.2 [flutter sqflite_common path]
- tuple 2.0.0 [quiver]
- url_launcher 6.0.20 [flutter url_launcher_android url_launcher_ios url_launcher_linux url_launcher_macos url_launcher_platform_interface url_launcher_web url_launcher_windows]

transitive dependencies:
- amplify_analytics_plugin_interface 0.4.1 [amplify_core flutter meta]
- amplify_api_plugin_interface 0.4.1 [amplify_core collection flutter json_annotation meta]
- amplify_auth_plugin_interface 0.4.1 [flutter meta amplify_core]
- amplify_core 0.4.1 [flutter plugin_platform_interface collection date_time_format meta uuid]
- amplify_datastore_plugin_interface 0.4.1 [flutter meta collection amplify_core]
- amplify_storage_plugin_interface 0.4.1 [flutter meta amplify_core]
- async 2.8.2 [collection meta]
- characters 1.2.0
- charcode 1.3.1
- clock 1.1.0
- collection 1.15.0
- cross_file 0.3.2 [flutter js meta]
- crypto 3.0.1 [collection typed_data]
- date_time_format 2.0.1
- ffi 1.1.2
- file 6.1.2 [meta path]
- flutter_plugin_android_lifecycle 2.0.5 [flutter]
- flutter_web_plugins 0.0.0 [flutter js characters collection material_color_utilities meta typed_data vector_math]
- font_awesome_flutter 9.2.0 [flutter]
- geolocator_android 3.1.0 [flutter geolocator_platform_interface]
- geolocator_apple 2.1.1+1 [flutter geolocator_platform_interface]
- geolocator_platform_interface 4.0.3 [flutter plugin_platform_interface vector_math meta]
- geolocator_web 2.1.4 [flutter flutter_web_plugins geolocator_platform_interface]
- geolocator_windows 0.1.0 [flutter geolocator_platform_interface]
- google_maps_flutter_platform_interface 2.1.4 [collection flutter meta plugin_platform_interface stream_transform]
- http_parser 4.0.0 [charcode collection source_span string_scanner typed_data]
- image_picker_for_web 2.1.4 [flutter flutter_web_plugins image_picker_platform_interface meta]
- image_picker_platform_interface 2.4.2 [flutter http meta plugin_platform_interface cross_file]
- js 0.6.3
- json_annotation 4.4.0 [meta]
- location_platform_interface 2.3.0 [flutter meta plugin_platform_interface]
- location_web 3.1.1 [flutter flutter_web_plugins http_parser js location_platform_interface meta]
- matcher 0.12.11 [stack_trace]
- material_color_utilities 0.1.3
- meta 1.7.0
- nested 1.0.0 [flutter]
- page_transition 2.0.5 [flutter]
- path_provider_android 2.0.12 [flutter path_provider_platform_interface]
- path_provider_ios 2.0.8 [flutter path_provider_platform_interface]
- path_provider_linux 2.1.5 [ffi flutter path path_provider_platform_interface xdg_directories]
- path_provider_macos 2.0.5 [flutter path_provider_platform_interface]
- path_provider_platform_interface 2.0.3 [flutter platform plugin_platform_interface]
- path_provider_windows 2.0.5 [ffi flutter path path_provider_platform_interface win32]
- permission_handler_android 9.0.2+1 [flutter permission_handler_platform_interface]
- permission_handler_apple 9.0.3 [flutter permission_handler_platform_interface]
- permission_handler_platform_interface 3.7.0 [flutter meta plugin_platform_interface]
- permission_handler_windows 0.1.0 [flutter permission_handler_platform_interface]
- platform 3.1.0
- plugin_platform_interface 2.1.2 [meta]
- process 4.2.4 [file path platform]
- qr 2.1.0 [meta]
- quiver 3.0.1+1 [matcher]
- shared_preferences_android 2.0.11 [flutter shared_preferences_platform_interface]
- shared_preferences_ios 2.1.0 [flutter shared_preferences_platform_interface]
- shared_preferences_linux 2.1.0 [file flutter path path_provider_linux path_provider_platform_interface shared_preferences_platform_interface]
- shared_preferences_macos 2.0.3 [flutter shared_preferences_platform_interface]
- shared_preferences_platform_interface 2.0.0 [flutter]
- shared_preferences_web 2.0.3 [flutter flutter_web_plugins shared_preferences_platform_interface]
- shared_preferences_windows 2.1.0 [file flutter path path_provider_platform_interface path_provider_windows shared_preferences_platform_interface]
- sky_engine 0.0.99
- source_span 1.8.1 [collection path term_glyph]
- sqflite_common 2.2.0 [synchronized path meta]
- stack_trace 1.10.0 [path]
- stream_transform 2.0.0
- string_scanner 1.1.0 [charcode source_span]
- synchronized 3.0.0
- term_glyph 1.2.0
- typed_data 1.3.0 [collection]
- url_launcher_android 6.0.15 [flutter url_launcher_platform_interface]
- url_launcher_ios 6.0.15 [flutter url_launcher_platform_interface]
- url_launcher_linux 3.0.0 [flutter url_launcher_platform_interface]
- url_launcher_macos 3.0.0 [flutter url_launcher_platform_interface]
- url_launcher_platform_interface 2.0.5 [flutter plugin_platform_interface]
- url_launcher_web 2.0.9 [flutter flutter_web_plugins url_launcher_platform_interface]
- url_launcher_windows 3.0.0 [flutter url_launcher_platform_interface]
- uuid 3.0.5 [crypto]
- vector_math 2.1.1
- win32 2.4.1 [ffi]
- xdg_directories 0.2.0+1 [meta path process]

Device

iPhone 13

OS

iOS 15.0.0

CLI Version

7.6.22

Additional Context

No response

Jordan-Nelson commented 2 years ago

Hello @irisk29 - Thanks for opening the issue. A few questions:

  1. Are you seeing any errors when saving the models?
  2. Have you attempted to query the models from your app after saving them? Are they getting saved to the local device at least?
irisk29 commented 2 years ago

Hello @Jordan-Nelson, I believe the problem was caused by the relation of the product to the shoppingBag. Only when I had a shopping bag connected to the product, I could save it. The question is why? I defined this field(the shopping bag id) as not required, to simulate 0..1 relation with the product (product can have 0 or 1 shopping bag) but still could not save the product without the shopping bag ID.

Jordan-Nelson commented 2 years ago

Only when I had a shopping bag connected to the product, I could save it

What was happening when you attempted to save without a shopping bag connected to the product? Was there an exception thrown?

irisk29 commented 2 years ago

What was happening when you attempted to save without a shopping bag connected to the product? Was there an exception thrown?

No exception was thrown, nothing happened. The state of the information in the cloud was like in the pictures attached.

Jordan-Nelson commented 2 years ago

Only when I had a shopping bag connected to the product, I could save it.

Do you mind explaining what you mean by this? Were you able to get this to work by changing either your schema, or the code being run?

irisk29 commented 2 years ago

Do you mind explaining what you mean by this? Were you able to get this to work by changing either your schema, or the code being run?

I had to change the code being run. I needed to create the ShoppingBagModel, save it, and then connect the ID of it to the product of the store I wanted to create. Even though, my intention was to be able to create a product for a store without necessarily creating a shopping bag for the product (for which it needs to belong).

Jordan-Nelson commented 2 years ago

@irisk29 - The schema that you shared only has ProductModel and OnlineStoreModel. Can you share the schema for ShoppingBagModel as well?

irisk29 commented 2 years ago

@irisk29 - The schema that you shared only has ProductModel and OnlineStoreModel. Can you share the schema for ShoppingBagModel as well?

type ShoppingBagModel @model @auth(rules: [{allow: public}]) {
  id: ID!
  productsAndQuantity: AWSJSON
  usermodelID: ID @index(name: "byUserModel")
  productModel: [ProductModel] @hasMany(indexName: "byShoppingBagModel", fields: ["id"])
  onlineStoreModel: OnlineStoreModel @hasOne
}
Jordan-Nelson commented 2 years ago

@HuiSF - This looks similar to https://github.com/aws-amplify/amplify-flutter/issues/1451. Does this look like the same issue to you?

HuiSF commented 2 years ago

Thanks @Jordan-Nelson for the initial triaging. Hello @irisk29 for reporting this issue. This is actually a known issue happening in the AppSync transformer:

When a field is used as a Global Secondary Index -

The underlying GraphQL mutation will be rejected by DynamoDB as this field will be assigned a null value by default. Amplify CLI maintainers is currently looking into this issue as https://github.com/aws-amplify/amplify-cli/issues/9915

There is no convenient workaround now unfortunately to 100% replicate your current model structure. (I believe you created the models using Amplify Studio data modeling interface?)

Here's what I do to get around of this personally.

type ProductModel @model @auth(rules: [{allow: public}]) {
  id: ID!
  name: String
  categories: AWSJSON
  price: Float
  imageUrl: String
  description: String
  onlinestoremodelID: ID @index(name: "byOnlineStoreModel")
  onlineStore: OnlineStoreModel @belongsTo(fields: ["onlinestoremodelID"])
  shoppingbagmodelID: ID @index(name: "byShoppingBagModel")
  shoppingBag: ShoppingBagModel @belongsTo(fields: ["shoppingbagmodelID"])
}

Please note that currently Amplify Studio Data modeling interface doesn't support @belongsTo directive. So you were planning adapt this workaround, you would need to stay with Amplify CLI dev cycle until Amplify Studio supports it.

I'm going to close this issue in favor of #306 . Please feel to follow up if you have any other question.