Closed jaymeen-unadkat-differenz closed 8 months ago
Hello, Thank you for posting this. Can you share your model schema, verbose logs(without sensitive information) and code snippets you're using? This will help us understand the issue better and reproduce it locally.
Schema:
enum WholesalerType {
CLASSA
CLASSB
}
type Wholesaler @model @auth(rules: [{allow: public}]) {
id: ID!
name: String
ordersEmail: String
type: WholesalerType
}
enum ProductCategory {
WHISKEY
GIN
LAGER
PILSNER
CABERNET
CHARDONNAY
}
enum ProductType {
SPIRITS
WINE
BEER
NONALCOHOLIC
}
type Product @model @auth(rules: [{allow: public}]) {
id: ID!
name: String
description: String
imageUrl: String
type: ProductType
cost: Int
category: ProductCategory
campaignProduct: [CampaignProduct] @hasMany
productLogoUrl: String
wholesaler: Wholesaler @hasOne
}
type CampaignProduct @model @auth(rules: [{allow: public}]) {
id: ID!
quantity: Int
campaignID: ID! @index(name: "byCampaign")
product: Product @belongsTo
primaryProduct: Boolean
}
enum DrinkType {
BEER
WINE
COCKTAIL
NONALCOHOLIC
}
type Drink @model @auth(rules: [{allow: public}]) {
id: ID!
name: String
type: DrinkType
description: String
imageURL: String
numberOfDrinks: Int
campaigns: [Campaign] @hasMany
}
enum RetailerType {
ONPREMISE
OFFPREMISE
}
enum CampaignStatus {
PENDING
LIVE
FINISHED
}
type RetailManager @model @auth(rules: [{allow: public}]) {
id: ID!
name: String
cognitoID: String
retailerID: ID! @index(name: "byRetailer")
test: String
campaignParticipation: [CampaignParticipation] @hasMany
}
type CampaignParticipation @model @auth(rules: [{allow: public}]) {
id: ID!
retailer: Retailer @belongsTo(fields: ["retailerID"])
retailerID: ID! @index(name: "byRetailer")
campaign: Campaign @belongsTo(fields: ["campaignID"])
campaignID: ID! @index(name: "byCampaign")
startingNumberOfOffers: Int
remainingNumberOfOffers: Int
retailManagerID: ID
retailManager: RetailManager @belongsTo
campaignStatus: CampaignStatus
}
type Retailer @model @auth(rules: [{allow: public}]) {
id: ID!
Name: String
campaignParticipations: [CampaignParticipation] @hasMany(indexName: "byRetailer", fields: ["id"])
retailManagers: [RetailManager] @hasMany(indexName: "byRetailer", fields: ["id"])
street: String
city: String
state: String
zipcode: String
lat: String
lng: String
description: String
imageURL: String
type: RetailerType
operatingHours: AWSJSON
wholesaler: Wholesaler @hasOne
}
type Campaign @model @auth(rules: [{allow: public}]) {
id: ID!
Name: String
numberOfCampaigns: Int
numberOfOffers: Int
campaignParticipations: [CampaignParticipation] @hasMany(indexName: "byCampaign", fields: ["id"])
description: String
publishDate: AWSDateTime
expirationDate: AWSDateTime
status: CampaignStatus
eligibleZipCodes: [String]
imageURL: String
drink: Drink @belongsTo
campaignProducts: [CampaignProduct] @hasMany(indexName: "byCampaign", fields: ["id"])
numberOfCampaignsRemaining: String
}
Sometimes Errors are like this
Creating not loaded list of CampaignProduct with Metadata(appSyncAssociatedIdentifiers: ["xxxxxx"], appSyncAssociatedFields: ["campaign"], apiName: nil)
Creating not loaded list of AcceptedCampaigns with Metadata(appSyncAssociatedIdentifiers: ["xxxxx"], appSyncAssociatedFields: ["campaign"], apiName: nil)
Anyone?
Hi @jaymeen-unadkat-differenz, taking a look. Here's the formatted error you are seeing is an error from AppSync on the subscription event.
onUpdateValueListener: data(
Swift.Result<
AWSPluginsCore.MutationSync<AWSPluginsCore.AnyModel>,
Amplify.GraphQLResponseError<AWSPluginsCore.MutationSync<AWSPluginsCore.AnyModel>>
>.failure(
GraphQLResponseError<MutationSync<AnyModel>>: GraphQL service returned a partially-successful response containing errors: [
Amplify.GraphQLError(
message: "Cannot return null for non-nullable type: \'AWSDateTime\' within parent \'Drink\' (/onUpdateCampaign/drink/createdAt)",
locations: nil,
path: Optional([
Amplify.JSONValue.string("onUpdateCampaign"),
Amplify.JSONValue.string("drink"),
Amplify.JSONValue.string("createdAt")
]),
extensions: nil
),
Amplify.GraphQLError(
message: "Cannot return null for non-nullable type: \'AWSDateTime\' within parent \'Drink\' (/onUpdateCampaign/drink/updatedAt)",
locations: nil,
path: Optional([
Amplify.JSONValue.string("onUpdateCampaign"),
Amplify.JSONValue.string("drink"),
Amplify.JSONValue.string("updatedAt")
]),
extensions: nil
),
Amplify.GraphQLError(
message: "Cannot return null for non-nullable type: \'Int\' within parent \'Drink\' (/onUpdateCampaign/drink/_version)",
locations: nil,
path: Optional([
Amplify.JSONValue.string("onUpdateCampaign"),
Amplify.JSONValue.string("drink"),
Amplify.JSONValue.string("_version")
]),
extensions: nil
),
Amplify.GraphQLError(
message: "Cannot return null for non-nullable type: \'AWSTimestamp\' within parent \'Drink\' (/onUpdateCampaign/drink/_lastChangedAt)",
locations: nil,
path: Optional([
Amplify.JSONValue.string("onUpdateCampaign"),
Amplify.JSONValue.string("drink"),
Amplify.JSONValue.string("_lastChangedAt")
]),
extensions: nil
)
]
)
Recovery suggestion: The list of `GraphQLError` contains service-specific messages.
)
receive(_:): data(
Swift.Result<
AWSPluginsCore.MutationSync<AWSPluginsCore.AnyModel>,
Amplify.GraphQLResponseError<AWSPluginsCore.MutationSync<AWSPluginsCore.AnyModel>>
>.failure(
GraphQLResponseError<MutationSync<AnyModel>>: GraphQL service returned a partially-successful response containing errors: [
Amplify.GraphQLError(
message: "Cannot return null for non-nullable type: \'AWSDateTime\' within parent \'Drink\' (/onUpdateCampaign/drink/createdAt)",
locations: nil,
path: Optional([
Amplify.JSONValue.string("onUpdateCampaign"),
Amplify.JSONValue.string("drink"),
Amplify.JSONValue.string("createdAt")
]),
extensions: nil
),
Amplify.GraphQLError(
message: "Cannot return null for non-nullable type: \'AWSDateTime\' within parent \'Drink\' (/onUpdateCampaign/drink/updatedAt)",
locations: nil,
path: Optional([
Amplify.JSONValue.string("onUpdateCampaign"),
Amplify.JSONValue.string("drink"),
Amplify.JSONValue.string("updatedAt")
]),
extensions: nil
),
Amplify.GraphQLError(
message: "Cannot return null for non-nullable type: \'Int\' within parent \'Drink\' (/onUpdateCampaign/drink/_version)",
locations: nil,
path: Optional([
Amplify.JSONValue.string("onUpdateCampaign"),
Amplify.JSONValue.string("drink"),
Amplify.JSONValue.string("_version")
]),
extensions: nil
),
Amplify.GraphQLError(
message: "Cannot return null for non-nullable type: \'AWSTimestamp\' within parent \'Drink\' (/onUpdateCampaign/drink/_lastChangedAt)",
locations: nil,
path: Optional([
Amplify.JSONValue.string("onUpdateCampaign"),
Amplify.JSONValue.string("drink"),
Amplify.JSONValue.string("_lastChangedAt")
]),
extensions: nil
)
]
)
Recovery suggestion: The list of `GraphQLError` contains service-specific messages.
)
The message Cannot return null for non-nullable type: 'AWSDateTime' within parent 'Drink' (/onUpdateCampaign/drink/createdAt)
.
The relevant schema is the Campaign model, with a parent Drink model
type Campaign @model @auth(rules: [{allow: public}]) {
id: ID!
Name: String
numberOfCampaigns: Int
numberOfOffers: Int
campaignParticipations: [CampaignParticipation] @hasMany(indexName: "byCampaign", fields: ["id"])
description: String
publishDate: AWSDateTime
expirationDate: AWSDateTime
status: CampaignStatus
eligibleZipCodes: [String]
imageURL: String
drink: Drink @belongsTo
campaignProducts: [CampaignProduct] @hasMany(indexName: "byCampaign", fields: ["id"])
numberOfCampaignsRemaining: String
}
type Drink @model @auth(rules: [{allow: public}]) {
id: ID!
name: String
type: DrinkType
description: String
imageURL: String
numberOfDrinks: Int
campaigns: [Campaign] @hasMany
}
Can you clarify if you have the lazy loading feature enabled? This feature is required to decode data from Amplify Studio.
In cli.json
do you have the feature flag generateModelsForLazyLoadAndCustomSelectionSet
set to true? If you are setting it to true
now, please make sure to re-run amplify codegen models
to re-generate the proper files
@lawmicha this is set to false Whole schema
{ "features": { "graphqltransformer": { "addmissingownerfields": true, "improvepluralization": false, "validatetypenamereservedwords": true, "useexperimentalpipelinedtransformer": true, "enableiterativegsiupdates": true, "secondarykeyasgsi": true, "skipoverridemutationinputtypes": true, "transformerversion": 2, "suppressschemamigrationprompt": true, "securityenhancementnotification": false, "showfieldauthnotification": false, "usesubusernamefordefaultidentityclaim": true, "usefieldnameforprimarykeyconnectionfield": false, "enableautoindexquerynames": true, "respectprimarykeyattributesonconnectionfield": true, "shoulddeepmergedirectiveconfigdefaults": false, "populateownerfieldforstaticgroupauth": true }, "frontend-ios": { "enablexcodeintegration": true }, "auth": { "enablecaseinsensitivity": true, "useinclusiveterminology": true, "breakcirculardependency": true, "forcealiasattributes": false, "useenabledmfas": true }, "codegen": { "useappsyncmodelgenplugin": true, "usedocsgeneratorplugin": true, "usetypesgeneratorplugin": true, "cleangeneratedmodelsdirectory": true, "retaincasestyle": true, "addtimestampfields": true, "handlelistnullabilitytransparently": true, "emitauthprovider": true, "generateindexrules": true, "enabledartnullsafety": true, "generatemodelsforlazyloadandcustomselectionset": false }, "appsync": { "generategraphqlpermissions": true }, "latestregionsupport": { "pinpoint": 1, "translate": 1, "transcribe": 1, "rekognition": 1, "textract": 1, "comprehend": 1 }, "project": { "overrides": true } }, "debug": { "shareProjectConfig": true } }
@lawmicha We can even have a google meet if it is possible from your end
Please set it to true
and re-run amplify codegen models
and re-run the app, then try again with Amplify Studio sourced mutations.
The reason why "lazy loading" is required is because so Swift models support decoding data sourced from Amplify Studio.
Okay after enabling the lazy load the error got even bigger
resolve(reconciling([AWSPluginsCore.MutationSync
onUpdateValueListener: data(Swift.Result<AWSPluginsCore.MutationSync
That doesn't look like an error log, it looks like the model Imbybe
received on the subscription. Are you experiencing any specific issues with the app?
For real-time updates, try Amplify.DataStore.observe
to see updates from the local database. When you send updates from Amplify Studio, the DataStore client will receive the corresponding subscription event and save it to the local database. The save to the local database will emit an event to the observe
API (similar to the observeQuery API as well). The log you posted appears to be the decoded data from the subscription event. Can confirm if that data is updated locally?
The logs correspond to the data received with identifiers:
"model": {
"id": "RET#1#RET#1",
"instance": {
"pk": "RET#1",
"sk": "RET#1",
You can also view the SQLite database directly using something like https://sqlitebrowser.org/ . The DB path can be seen in the logs as
Initializing database connection: /Users/xxxx/Library/Developer/CoreSimulator/Devices/3C444803-AED8-4D45-9222-278A3F6FD089/data/Containers/Data/Application/E2DF561C-6992-46A9-A1D0-13FFFDEC7768/Documents/xxxx.db
if you have verbose logging enabled: Amplify.Logging.logLevel = .verbose
(set this before adding the plugin and Amplify.configure()
Hi @lawmicha I can see that, any updated data that is updated from studio which is being updating in local database "ImbybeTestDemo.db" but it is not updating in my ios application
Can you try this?
For real-time updates, try Amplify.DataStore.observe to see updates from the local database. When you send updates from Amplify Studio, the DataStore client will receive the corresponding subscription event and save it to the local database. The save to the local database will emit an event to the observe API (similar to the observeQuery API as well). The log you posted appears to be the decoded data from the subscription event. Can confirm if that data is updated locally?
Amplify.DataStore.observeQuery
actually uses Amplify.DataStore.observe
under the hood, so if observe
is not working, then observeQuery
won't work as well.
Amplify.DataStore.observe
documentation https://docs.amplify.aws/swift/build-a-backend/more-features/datastore/real-time/
I have used both none of them are working
Can you provide us with the verbose logs (Amplify.Logging.logLevel = .verbose
enabled) for the iOS app when it receives the subscription event?
Amplify.DataStore.start()
ready
event can be seen in the logs [Lifecycle event 6]: ready
After Performing mutation this are the logs that I'm getting
Logs
onUpdateValueListener: data(Swift.Result<AWSPluginsCore.MutationSync
@lawmicha have you checked?
The logs look good to me and the item appears to be reconciled.
Amplify.DataStore.observeQuery
performs a query to generate the first snapshot, if you perform an Amplify.Datastore.query(Imbybe.self)
, do you get a list of items back including the model that was reconciled? model identifier pk = DRI#1
and sk = DRI#1
?actor ViewModel {
// You must hold a reference to your subscription.
var imbybeSubscription: AmplifyAsyncThrowingSequence<DataStoreQuerySnapshot<Imbybe>>?
func subscribeToImbybe() async throws {
let imbybeSubscription = Amplify.DataStore.observeQuery(
for: Imbybe.self
)
// hold onto your subscription
self.imbybeSubscription = imbybeSubscription
// observe new snapshots
for try await snapshot in imbybeSubscription {
print("Snapshot: \(snapshot)")
}
}
}
observe
/observeQuery
APIs. Subscribe to the model from the second simulator before saving the model from the first simulatorNow the real-time is working in Observe(Model.self) but not working on ObserveQuery
Great to hear Observe
API is working as expected. Can you provide more details as to what's not working with ObserveQuery?
AmplifyAsyncThrowingSequence
? observeQuery
then save
. For other device see point (3) from https://github.com/aws-amplify/amplify-swift/issues/3495#issuecomment-1932535330 about using two simulators.I'm changing the approach actually, I'll keep you updated
thanks for letting us know, feel free to open a new issue once you have more details, refer back to this issue if relevant. You can also reach out to us on Discord https://discord.gg/jWVbPfC in swift-help topic
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.
Amplify.DataStore.observeQuery real-time data not updating
I'm getting data in Amplify.DataStore.observeQuery,
But when I update the value in the model from Amplify studio's data console
I get this error: I've been stuck for the past 15 days on this issue
Steps To Reproduce
Expected behavior
Data should update in the array(variable)
Amplify Framework Version
2.25.6
Amplify Categories
DataStore
Dependency manager
Swift PM
Swift version
5.9
CLI version
12.10.1
Xcode version
XCode 15
Relevant log output