aws-amplify / amplify-swift

A declarative library for application development using cloud services.
Apache License 2.0
455 stars 196 forks source link

Issue building models with amplify codegen models "Error: Value type of struct has infinite size" #1541

Closed horaciosolorio closed 1 year ago

horaciosolorio commented 2 years ago

Describe the bug

The generator works great in VueJS , but with the schema graphql when is generated and try to build project show me the error.

Value type 'Photo' has infinite size Value type 'Photo' cannot have a stored property that recursively contains it

This is the Model Screen Shot 2021-11-21 at 7 57 31

This is the generated file by "amplify codegen models" Screen Shot 2021-11-21 at 7 58 14

This is the pod librarys

Amplify

pod 'Amplify' pod 'AmplifyPlugins/AWSAPIPlugin' pod 'AmplifyPlugins/AWSCognitoAuthPlugin' pod 'AmplifyPlugins/AWSDataStorePlugin'

I am using the configuration in AppDelegate:

Amplify.Logging.logLevel = .verbose do { try Amplify.add(plugin: AWSAPIPlugin (modelRegistration: AmplifyModels())) try Amplify.configure() } catch { print("An error ocurred setting up Ampliy: (error)") }

This error stop bulding Xcode process.

Steps To Reproduce

Steps to reproduce the behavior:
1. Configure API and Graphql 
2. Run amplify codegen models
3. Build Xcode Project 
4. See error "Value type 'Photo' has infinite size" , "Value type 'Photo' cannot have a stored property that recursively contains it"

Expected behavior

When building project the models don't have this issue with infinite size.

Amplify Framework Version

1.16.1

Amplify Categories

API, Auth, Storage

Dependency manager

Cocoapods

Swift version

5.3.2

CLI version

7.4.4

Xcode version

12.4

Relevant log output

No response

Is this a regression?

No

Regression additional context

No response

Device

Iphone 12

iOS Version

IOS 14

Specific to simulators

No response

Additional context

No response

royjit commented 2 years ago

Can you provide the whole schema, to see if we have a reverse relationship from Place to Photo. We have an open issue related to 1-1 connection - https://github.com/aws-amplify/amplify-ios/issues/505 .

horaciosolorio commented 2 years ago

Adding Schema Screen Shot 2021-11-26 at 13 43 22

Screen Shot 2021-11-26 at 13 44 01

Screen Shot 2021-11-26 at 13 43 31

schema.graphql.zip

horaciosolorio commented 2 years ago

@royjit any update? , I am stuck with this issue please help me.

thisisabhash commented 2 years ago

Hello,

This is a known issue in iOS in case of bi-directional connections where one model has hasOne and other model has belongsTo relationship. Models are struct in Amplify iOS and therefore are value types. Swift doesn't allow recursive value types. We are continuously trying to improve DataStore and will post when we have further updates for this issue.

As a workaround, please try out the alternative schema below : schema.graphql.zip

Place has a new model LogoPhoto which takes in placeID as an ID for Place table so that Place can be queried when you have LogoPhoto instance.

type Place
@model
@searchable
@auth(
  rules: [
    { allow: owner, operations: [create, update, read] }
    { allow: private, provider: iam, operations: [ read ] }
    { allow: groups, groups: ["Admins"] }
  ]
)
{
  id: ID!
  name: String
  description: String
  logo: LogoPhoto @connection
  category: Category
  inNumber: String
  outNumber: String
  reference: String
  street: String
  colonia: Colonia @connection
  createdAt: String
  updatedAt: String
  photos: [Photo] @connection(name:"PlacePhotos", sortField: "createdAt")
  status: PlaceStatus
  location: Location
  schedules: Schedules @connection
  reasonForRejection: String,
  comments: String
}

type LogoPhoto
@model
{
  id: ID!
  placeID: ID!
  createdAt: String
  updatedAt: String
  contentType: String
  height: Int
  width: Int
}

Colonia has a placeID : ID! field instead of place : Place @connection which can be used to query for Place.

type Colonia
@model
@auth(
  rules: [
    { allow: owner }
    { allow: private, provider: iam, operations: [ read ] }
    { allow: groups, groups: ["Admins"] }
  ]
)
@key(name: "ColoniaByMunicipioIndex", fields: ["municipioId", "name"], queryField: "coloniasByMunicipioId")
@key(name: "ColoniaByPostalCodeIndex", fields: ["postalCode"], queryField: "coloniasByPostalCodeId")
{
  id: ID!
  municipioId: ID!
  name: String
  postalCode: String
  createdAt: String
  updatedAt: String
  municipio: Municipio @connection(name:"MunicipioColonias", sortField: "name")
  placeID: ID!
}
horaciosolorio commented 2 years ago

But what happened for a Colonia can assing to many places ?, this solution don't force to have one colonia assign to just one place ?

thisisabhash commented 2 years ago

Hello, thank you for your message. Yes, this solution doesn't enforce bidirectional relationship between Colonia and Place. We're currently investigating this and will post here with updates.

alharris-at commented 2 years ago

@horaciosolorio as mentioned above, circular references are not supported in datastore today. We'll use this issue to track two changes. First, we'll look at ways to fail faster when you're building your API and indicate that this is an invalid setup, and second to find a way to unblock circular refs across DataStore as a whole.

horaciosolorio commented 2 years ago

The issue was resolved ?

lawmicha commented 2 years ago

Hi @horaciosolorio, this issue is still open, bi-directional has-one belongs-to relationships do not work on iOS as mentioned above. We have some ideas for moving forward such as encapsulating the association within another type or using a property wrapper and will provide updates here when we can.

pljhll commented 1 year ago

Hi team. Being able to use the bi-directional on iOS would certainly be nice. Although I appreciate this is a Swift language issue you're having to work around. Would it be possible to get an update on this one?

ameter commented 1 year ago

Bi-direction support has been added in the Lazy Loading feature that was released in version 2.4.0. This should address this issue.

This support requires the lazy loading feature flag. Please use the latest version of the amplify CLI and review or make updates to cli.json (in the amplify folder) to ensure you have the following settings:

"transformerversion":2 "respectprimarykeyattributesonconnectionfield": true "generatemodelsforlazyloadandcustomselectionset": true

Please open a new issue if this does not resolve the problem.