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

Datastore HasOne connection never populated #1107

Closed
ForeandAft opened this issue Mar 16, 2021 · 8 comments
Closed

Datastore HasOne connection never populated #1107

ForeandAft opened this issue Mar 16, 2021 · 8 comments
Assignees
Labels
bug Something isn't working datastore Issues related to the DataStore category

Comments

@ForeandAft
Copy link

ForeandAft commented Mar 16, 2021

Describe the bug
When specifying a HasOne connection as described in the documentation (https://docs.amplify.aws/cli/graphql-transformer/connection#has-one), the linked child object is never populated when querying from AppSync.

To Reproduce
Defined as model as shown:

type NomadUser @model @auth(rules: [{ allow: owner, ownerField: "cognitoId", operations: [create, update, delete] },
{ allow: private, provider: iam, operations: [create, update, delete] }])
@key(fields: ["cognitoId", "id"], name: "NomadUsersByCognitoId") {
	id: ID!
	screenName: String
	fullName: String!
	aboutMe: String
	website: AWSURL
	facebookLink: AWSURL
	twitterLink: String
	instagramLink: String
	youTubeLink: AWSURL
	childrenAges: [String]
	interests: [String]
}
type NomadBlockedUser @model @auth(rules: [{ allow: owner, ownerField: "owner", operations: [read, create, delete] },
	{ allow: private, provider: iam, operations: [create, update, delete] }])
    @key(fields: ["owner", "id"], name: "blockedUsersbyOwner")
		@key(fields: ["blockedProfileID", "id"], name: "blocksByBlockedProfileID")
{
    id: ID!
    owner: String
    blockedProfileID: ID!
    blockedProfile: NomadUser @connection(fields: ["blockedProfileID"])
		blockedCognitoId: String
}

After codgen completed I am able to insert objects into the datastore and DynamoDB successfully. I can query the child object from the AppSync Query tool as well

However, when I query the DataStore as shown:

Amplify.DataStore.query(NomadBlockedUser.self, where: keys.owner == SecurityManager.shared.currentUserSub, sort: nil, paginate: nil) { (result) in
            switch result{
            case.success(let data):
                onCompletion(data, nil)
                if let profile = data[0].blockedProfile
                {
                    print(profile.aboutMe)
                }
            case .failure(let error):
                print("Error")
            }
        }
    }

the child profile object is always nil. I have confirmed that even if the data is being lazy-loaded from the local store, this should still work because the NomadUser that I have blocked is in the local data store.

Expected behavior
I expect the BlockedProfile object to be populated when querying the datastore.

Environment(please complete the following information):
Amplify Framework 1.6.1
Dependency Manager Cocoapods
Swift 5.0
Amplify version 4.45.2

Device Information (please complete the following information):

  • Device: iPhone 12pro Simulator
  • iOS Version: iOS 14

Additional context
Add any other context about the problem here.

@royjit royjit added datastore Issues related to the DataStore category pending-triage Issue is pending triage question General question labels Mar 16, 2021
@kneekey23
Copy link
Contributor

Experiencing this as well :(

@diegocstn diegocstn removed the pending-triage Issue is pending triage label Mar 26, 2021
@palpatim
Copy link
Member

palpatim commented Apr 9, 2021

Summary from @diegocstn

  • couldn't repro with the simplest scheme possible (no auth rules)
  • couldn't repro with following schema
type Team @model @auth(rules: [{ allow: owner, operations: [create, update, delete] }]) {
  id: ID!
  name: String!
}

type Project @model @auth(rules: [{ allow: owner, operations: [read, create, delete] }]) {
  id: ID!
  name: String
  team: Team @connection
}

Next Steps

  • Check status of sqlite: Is the data even there?
  • Assuming it's not (which seems like a safe assumption), progressively add rules using @kneekey23's schema & auth config as a guide, until we find a config that reproduces the issue

@diegocstn diegocstn self-assigned this Apr 12, 2021
@diegocstn diegocstn added bug Something isn't working and removed question General question labels Apr 15, 2021
@github-actions
Copy link
Contributor

This issue is stale because it has been open for 14 days with no activity. Please, provide an update or it will be automatically closed in 7 days.

@github-actions github-actions bot added the closing soon This issue will be closed in 7 days unless further comments are made. label Apr 30, 2021
@diegocstn diegocstn removed the closing soon This issue will be closed in 7 days unless further comments are made. label Apr 30, 2021
@palpatim palpatim added the pending-triage Issue is pending triage label May 4, 2021
@kwomackcodes
Copy link

kwomackcodes commented May 7, 2021

Also experienced this! The connection works with

type Project @model @auth(rules: [{ allow: owner, operations: [read, create, delete] }]) {
  id: ID!
  name: String
  team: Team @connection
}

but fails with

type Project @model @auth(rules: [{ allow: owner, operations: [read, create, delete] }]) {
  id: ID!
  name: String
  teamID: String!
  team: Team @connection(fields: ["teamID"]
}

is this being fixed?

@palpatim
Copy link
Member

Thanks for taking the time to comment. We’re working on ways to make DataStore relationships simpler. Once we get that done, we may need to adjust code in the DataStore plugin to properly handle the situation above. We’ll update this issue when we have more information.

@Jordan-Nelson
Copy link
Member

Jordan-Nelson commented Jun 25, 2021

Also experienced this! The connection works with

type Project @model @auth(rules: [{ allow: owner, operations: [read, create, delete] }]) {
  id: ID!
  name: String
  team: Team @connection
}

but fails with

type Project @model @auth(rules: [{ allow: owner, operations: [read, create, delete] }]) {
  id: ID!
  name: String
  teamID: String!
  team: Team @connection(fields: ["teamID"]
}

is this being fixed?

@palpatim @diegocstn - I think it is worth noting that the second schema creates a .hasOne ModelAssociation, whereas the first schema actually creates a .belongsTo ModelAssociation (see screenshot below that shows this). It is not always transparent to the consumer what type of ModelAssociation is being used. But the fact that one schema works and the other does not is consistent with the original issue. The data only seems to return for .belongsTo associations, and not .hasOne associations.

Probably adding to the confusion/issue is that both of these schemas are called out as examples of hasOne relations in the CLI docs. It seems like either the docs need to be updated or the ModelAssociation used should be updated.

Note: the first schema being represented with .belongsTo and the second with .hasOne is consistent with amplify-android from what I have observed.

Screenshot of first schema being represented with a .belongsTo ModelAssociation:

Screen Shot 2021-06-24 at 5 24 28 PM

@anoop4real
Copy link

Is there any update on this issue?

@lawmicha lawmicha added the p2 label Jun 8, 2022
@diegocstn diegocstn removed their assignment Jun 28, 2022
igorTimofiejczyk added a commit to AnimealProject/animeal_iOS that referenced this issue Aug 31, 2022
Amplify have known issue which prevent to fill properties with .hasOne connection
Here the issue:
aws-amplify/amplify-swift#1107
And here the prepared fix:
aws-amplify/amplify-swift#1676

Since fix was on github for while without any changes I switched the to the forked version of amplify
igorTimofiejczyk added a commit to AnimealProject/animeal_iOS that referenced this issue Aug 31, 2022
Amplify have known issue which prevent to fill properties with .hasOne connection
Here the issue:
aws-amplify/amplify-swift#1107
And here the prepared fix:
aws-amplify/amplify-swift#1676

Since fix was on github for while without any changes I switched the to the forked version of amplify
igorTimofiejczyk added a commit to AnimealProject/animeal_iOS that referenced this issue Aug 31, 2022
Amplify have known issue which prevent to fill properties with .hasOne connection
Here the issue:
aws-amplify/amplify-swift#1107
And here the prepared fix:
aws-amplify/amplify-swift#1676

Since fix was on github for while without any changes I switched the to the forked version of amplify
igorTimofiejczyk added a commit to AnimealProject/animeal_iOS that referenced this issue Sep 1, 2022
Amplify have known issue which prevent to fill properties with .hasOne connection
Here the issue:
aws-amplify/amplify-swift#1107
And here the prepared fix:
aws-amplify/amplify-swift#1676

Since fix was on github for while without any changes I switched the to the forked version of amplify
@thisisabhash
Copy link
Member

Hello,
Thank you for your patience in this and we apologize for our delay in response. We have made several improvements in Datastore and API in recent releases, mainly the feature called Lazy Loading. Please upgrade your CLI version to >10.8.0 and Amplify version >2.4.0 to use this feature. Follow the steps here :
https://docs.amplify.aws/cli/migration/lazy-load-custom-selection-set/#lazy-loading-connected-models

For reference, I used the following schema and code snippet. I was able to fetch the blockedProfile inside NomadBlockedUser. I have attached a screenshot of the console log as well.

type NomadUser @model 
@auth(rules: [{ allow: public }]){
	id: ID!
	screenName: String
	fullName: String!
	aboutMe: String
}

type NomadBlockedUser @model 
@auth(rules: [{ allow: public }])
{
    id: ID!
    owner: String
    blockedProfileID: ID!
    blockedProfile: NomadUser @hasOne(fields: ["blockedProfileID"])
		blockedCognitoId: String
}

func createUserAndQuery() async {
        do {
            let nomadUser = NomadUser(fullName: "dummyUser")
            let savedNomadUser = try await Amplify.DataStore.save(nomadUser)
            print("[GH1107]Saved user: \(savedNomadUser)")
            let nomadBlockedUser = NomadBlockedUser(blockedProfileID: nomadUser.id)
            let savedNomadBlockedUser = try await Amplify.DataStore.save(nomadBlockedUser)
            print("[GH1107]Saved blocked user: \(savedNomadBlockedUser)")
            let queriedBlockedUsers = try await Amplify.DataStore.query(NomadBlockedUser.self)
            print("[GH1107]Queried blocked user list count: \(queriedBlockedUsers.count)")
            let blockedUser = queriedBlockedUsers[0]
            let containedUser = try await blockedUser.blockedProfile
            print("[GH1107]Contained user: \(String(describing: containedUser))")
        } catch {
            print("[GH1107]Failed with error : \(error)")
        }
    }

GH1107

@thisisabhash thisisabhash added closing soon This issue will be closed in 7 days unless further comments are made. and removed follow up Requires follow up from maintainers labels May 11, 2023
@github-actions github-actions bot removed the closing soon This issue will be closed in 7 days unless further comments are made. label Jun 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working datastore Issues related to the DataStore category
Projects
None yet
Development

No branches or pull requests