Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
2 of 9 tasks
irisk29 opened this issue Mar 8, 2022 · 10 comments
Closed
2 of 9 tasks

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

irisk29 opened this issue Mar 8, 2022 · 10 comments
Assignees
Labels
datastore Issues related to the DataStore Category duplicate This issue or pull request already exists pending-triage This issue is in the backlog of issues to triage

Comments

@irisk29
Copy link

irisk29 commented Mar 8, 2022

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

  • Analytics
  • API (REST)
  • API (GraphQL)
  • Auth
  • Authenticator
  • DataStore
  • Storage

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

  • iOS
  • Android

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 Jordan-Nelson added datastore Issues related to the DataStore Category pending-triage This issue is in the backlog of issues to triage labels Mar 8, 2022
@Jordan-Nelson
Copy link
Member

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?

@Jordan-Nelson Jordan-Nelson added the pending-community-response Pending response from the issue opener or other community members label Mar 10, 2022
@irisk29
Copy link
Author

irisk29 commented Mar 10, 2022

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 Jordan-Nelson removed the pending-community-response Pending response from the issue opener or other community members label Mar 10, 2022
@Jordan-Nelson
Copy link
Member

Jordan-Nelson commented Mar 10, 2022

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?

@Jordan-Nelson Jordan-Nelson added the pending-community-response Pending response from the issue opener or other community members label Mar 10, 2022
@irisk29
Copy link
Author

irisk29 commented Mar 10, 2022

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
Copy link
Member

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
Copy link
Author

irisk29 commented Mar 11, 2022

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 Jordan-Nelson removed the pending-community-response Pending response from the issue opener or other community members label Mar 14, 2022
@Jordan-Nelson
Copy link
Member

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

@Jordan-Nelson Jordan-Nelson added the pending-community-response Pending response from the issue opener or other community members label Mar 14, 2022
@irisk29
Copy link
Author

irisk29 commented Mar 14, 2022

@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 Jordan-Nelson removed the pending-community-response Pending response from the issue opener or other community members label Mar 14, 2022
@Jordan-Nelson
Copy link
Member

@HuiSF - This looks similar to #1451. Does this look like the same issue to you?

@HuiSF
Copy link
Member

HuiSF commented Mar 14, 2022

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 -

  • This field is not used as connection field (like in your schema, shoppingbagmodelID is not actually associating the Bag model using @belongsTo)
  • This field is not assigned a value when saving the model

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 aws-amplify/amplify-cli#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.

  • Update the schema as following (making bi-directional has many relationship) and amplify push to deploy the schema
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"])
}
  • With this update, you should be able to save model even when not assigning a proper value to both onlinestoremodelID and shoppingbagmodelID fields.
  • Code example to save models
    var storeModel = ...
    var bagModel = ...
    // note that we assign to the model field instead of the connection id fields
    var product = ProductModel(name: 'A product', onlineStore: storeModel, shoppingBag: bagModel);
    await Amplify.DataStore.save(product);

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.

@HuiSF HuiSF closed this as completed Mar 14, 2022
@HuiSF HuiSF added the duplicate This issue or pull request already exists label Mar 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
datastore Issues related to the DataStore Category duplicate This issue or pull request already exists pending-triage This issue is in the backlog of issues to triage
Projects
None yet
Development

No branches or pull requests

3 participants