Closed tappready closed 3 years ago
@tappready Thanks for the details. Can you confirm that you used either Amplify Tools build plugin, or amplify codegen models
to regenerate your local models after upgrading Amplify CLI to 4.22.0? I'm not sure whether that would make a difference, but it's good to verify.
@tappready While we're looking into this, I wanted to call out one other thing. In your configuration code, you specify syncInterval
of 30
. Unfortunately, this documentation is incorrect. syncInterval
actually refers to the maximum interval the system will continue to perform "catch-up" queries. After this interval expires, the system performs a "base" query and retrieves all data.
The actual times at which DataStore performs the sync query aren't directly under your control. Rather, DataStore runs a sync query when it starts new subscriptions: app startup, app returning from foreground, or app restoring network connectivity. At that time, it checks the time at which it performed a "base" query. If less than syncInterval
seconds have elapsed since the last "base" query, DataStore runs a "catch-up" query, asking only for data since the last "base" query. Otherwise, if syncInterval
has elapsed, DataStore performs a full "base" query and resets the time.
While DataStore is in the foreground and connected, it automatically receives subscriptions from your cloud API via GraphQL subscriptions, so there is no need to specify an aggressive syncInterval
to catch those updates.
The default value of syncInterval
is 24 hours. So that means if a user of your app launches and retrieves all of their data. The system wouldn't need to perform another full query until 24 hours have elapsed, even if the user quits the app, or backgrounds/foregrounds it, or loses and then restores network.
Hope this clarifies. We'll be fixing the documentation to make that clearer. In the meantime, I'd suggest you can remove your custom configuration.
And of course, we're continuing to investigate the actual bug report. :)
@tappready Thanks for the details. Can you confirm that you used either Amplify Tools build plugin, or
amplify codegen models
to regenerate your local models after upgrading Amplify CLI to 4.22.0? I'm not sure whether that would make a difference, but it's good to verify.
I have tried with both
@tappready While we're looking into this, I wanted to call out one other thing. In your configuration code, you specify
syncInterval
of30
. Unfortunately, this documentation is incorrect.syncInterval
actually refers to the maximum interval the system will continue to perform "catch-up" queries. After this interval expires, the system performs a "base" query and retrieves all data.The actual times at which DataStore performs the sync query aren't directly under your control. Rather, DataStore runs a sync query when it starts new subscriptions: app startup, app returning from foreground, or app restoring network connectivity. At that time, it checks the time at which it performed a "base" query. If less than
syncInterval
seconds have elapsed since the last "base" query, DataStore runs a "catch-up" query, asking only for data since the last "base" query. Otherwise, ifsyncInterval
has elapsed, DataStore performs a full "base" query and resets the time.While DataStore is in the foreground and connected, it automatically receives subscriptions from your cloud API via GraphQL subscriptions, so there is no need to specify an aggressive
syncInterval
to catch those updates.The default value of
syncInterval
is 24 hours. So that means if a user of your app launches and retrieves all of their data. The system wouldn't need to perform another full query until 24 hours have elapsed, even if the user quits the app, or backgrounds/foregrounds it, or loses and then restores network.Hope this clarifies. We'll be fixing the documentation to make that clearer. In the meantime, I'd suggest you can remove your custom configuration.
And of course, we're continuing to investigate the actual bug report. :)
That integer was just a suggestion from a member on discord I have removed this since sorry for including it
hi @tappready, thanks for reporting this issue. Taking a look at the schema:
type UserProfile
@model(timestamps:{createdAt: "createdOn", updatedAt: "updatedOn"})
@auth(rules: [{ allow: owner, groups: ["Users"] operations: [create, update, read] }])
{
id: ID!,
name: String
weightHistory: [WeightHistory]
}
type WeightHistory {
weight: Float!,
dateTime: AWSDateTime!
}
type DietaryRequirement
@model
@auth(rules: [{ allow: public, operations: [read] }])
@key(name: "orderBy", fields: ["listOrder"])
{
id: ID!,
description: String!,
listOrder: Int!
}
UserProfile
, you have allow: owner
which provides access to the model for authenticated users.
groups: ["Users"]
is used in conjuntion with allow: groups
for static group authorizion so it has no effect here. This can be verified by creating a user, not in the Cognito group "Users", sign in via AppSync Queries console, and making a create mutation request to successfully create a UserProfile. You can omit the groups: ["Users:]
operations: [create, update, read]
also restricts acess to authenticated users to allow create, update, and read the data. By omitting 'delete' from the operations, this means anyone can delete the data given that they are somehow are able to get a hold of the id. I noticed the provisioned backend restricts delete subscription operations to only authenciated users which is why you are seeing the subscription failures. Is your use case actually to allow anyone to delete this data? If not, this will work:
type UserProfile
@model(timestamps:{createdAt: "createdOn", updatedAt: "updatedOn"})
@auth(rules: [{ allow: owner, operations: [create, update, read, delete] }]) // you can also omit `operations` all together, it will default the same shown here
{
id: ID!,
name: String
weightHistory: [WeightHistory]
}
If you require the user to be in the cognito user group, use allow: groups
and groups
:
type UserProfile
@model(timestamps:{createdAt: "createdOn", updatedAt: "updatedOn"})
@auth(rules: [{ allow: groups, groups: ["Users"], operations: [create, update, read, delete] }])
{
id: ID!,
name: String
weightHistory: [WeightHistory]
}
DietaryRequirement
, the allow:public
requires the request to be signed with the API key. With operations: [read]
you then restrict requests with api key to only allow read operations. Then which users should be able to create the data? Consider combining authorization modes, the example translates to
type DietaryRequirement
@model
@auth(rules: [
{ allow: owner },
{ allow: public, operations: [read] }])
@key(name: "orderBy", fields: ["listOrder"])
{
id: ID!,
description: String!,
listOrder: Int!
}
Only signed in users can create/update/delete/read DietaryRequirement, and requests with api key can only read the data.
This use case creates a single endpoint with multiple auth modes (APIKey, Cognito user pool). One limitation to keep in mind is that DataStore depends on a single API configured. You'll want to make sure your default auth mode is Cognito user pool and additional auth types is API Key (not the other way around)
Choose the default authorization type for the API `Amazon Cognito User Pool`
Use a Cognito user pool configured as a part of this project.
? Do you want to configure advanced settings for the GraphQL API `Yes, I want to make some additional
changes.`
? Configure additional auth types? `Yes`
? Choose the additional authorization types you want to configure for the API `API key`
and also make sure DataStore conflict resolution is enabled when using Amplify.DataStore
? Configure conflict detection? `Yes`
? Select the default resolution strategy `Auto Merge`
the resulting amplifyconfiguration.json
should be the Cognito User Pool authorization Type for the endpoint
"api": {
"plugins": {
"awsAPIPlugin": {
"[friendlyAPIName]": {
"endpointType": "GraphQL",
"endpoint": "https://<your endpoint>.us-west-2.amazonaws.com/graphql",
"region": "us-west-2",
"authorizationType": "AMAZON_COGNITO_USER_POOLS"
I have tested this Amplify Library 1.0.4 and Amplify CLI 4.22.0. Now you can make requests from other places like a web app for the public data by adding API Key to your request to the same AppSync endpoint. When the app is running with DataStore, the subscriptions are expected to fail until the user is signed in. Hope that clears up some of the usage around the auth and model directives.
Hi @lawmicha, thank you so much for your response, time and effort.
I have since removed the groups declaration from my auth. Me omitting 'delete' from the array of operations was an attempt to restrict users from deleting. The 'DietaryRequirement' model is static data that should allow all users and non user to read.
I have taken on board your suggestions with regards to auth and after testing by signing up a user with confirmation code and then checking if the user is signed in I then attempt to save the user profile and still get the same errors in the log and nothing is synced to the cloud (DynamoDB), only saved locally.
On another note, after inspecting the User Profile that was saved locally, I noticed that there is no column linking the model to the congnito user? is this correct?
The log after the user confirms with auth code:
2020-07-10 08:39:46.065168+0100 MyBodyBud[3498:60089] [RemoteSyncEngine] pauseSubscriptions() 2020-07-10 08:39:46.065509+0100 MyBodyBud[3498:60089] [RemoteSyncEngine] pauseMutations() 2020-07-10 08:39:46.065755+0100 MyBodyBud[3498:60089] [RemoteSyncEngine] clearStateOutgoingMutations(storageAdapter:) 2020-07-10 08:39:46.066739+0100 MyBodyBud[3498:60089] [RemoteSyncEngine] initializeSubscriptions(api:storageAdapter:) 2020-07-10 08:39:46.069570+0100 MyBodyBud[3498:60089] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received subscription: PassthroughSubject 2020-07-10 08:39:46.072265+0100 MyBodyBud[3498:60089] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received subscription: PassthroughSubject 2020-07-10 08:39:46.074115+0100 MyBodyBud[3498:60089] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received subscription: PassthroughSubject 2020-07-10 08:39:46.075873+0100 MyBodyBud[3498:60089] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received subscription: PassthroughSubject 2020-07-10 08:39:46.164996+0100 MyBodyBud[3498:60340] Connecting to url ... 2020-07-10 08:39:46.417946+0100 MyBodyBud[3498:60340] WebsocketDidConnect 2020-07-10 08:39:46.418074+0100 MyBodyBud[3498:60340] WebsocketDidConnect, sending init message... 2020-07-10 08:39:46.418167+0100 MyBodyBud[3498:60340] Validating connection 2020-07-10 08:39:46.418303+0100 MyBodyBud[3498:60340] WebsocketDidReceiveMessage - {"payload":{"errors":[{"message":"Both, the \"header\", and the \"payload\" query string parameters are missing","errorCode":400}]},"type":"connection_error"} 2020-07-10 08:39:46.418827+0100 MyBodyBud[3498:60340] The data couldn’t be read because it isn’t in the correct format. 2020-07-10 08:39:46.419231+0100 MyBodyBud[3498:60340] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.) 2020-07-10 08:39:46.419551+0100 MyBodyBud[3498:60340] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.) 2020-07-10 08:39:46.419782+0100 MyBodyBud[3498:60340] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.) 2020-07-10 08:39:46.419859+0100 MyBodyBud[3498:60336] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received completion: failure(DataStoreError: subscription item event failed with error Caused by: APIError: subscription item event failed with error Caused by: jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil)))))
Hi @tappready just to make sure nothing is lost in translation, could you provide us with the schema you are using now?
@lawmicha please find bellow my current schema: ` ########################################
########################################
type UserProfile
@model(timestamps:{createdAt: "createdOn", updatedAt: "updatedOn"})
@auth(rules: [{ allow: owner }])
{
id: ID!,
name: String,
gender: String,
activityLevel: String,
occupationActivity: String,
weeklyGoal: String,
bodyType: String,
dietryRequirments: [String],
height: Float,
mesureSystem: String,
firstMealTime: AWSTime,
weightHistory: [WeightHistory],
bmiHistory: [BMIHistory],
favouriteFood: [FavouriteFood]
}
type WeightHistory {
weight: Float!,
dateTime: AWSDateTime!
}
type BMIHistory {
bmi: Float!,
dateTime: AWSDateTime!
}
type FavouriteFood {
id: ID!,
name: String!,
source: String!,
imageURL: AWSURL,
healthLabel: String,
}
########################################
########################################
type ActivityLevel
@model
@auth(rules: [
{ allow: owner },
{ allow: public, operations: [read] }])
@key(name: "orderBy", fields: ["listOrder"])
{
id: ID!,
description: String!,
listOrder: Int!
}
type OccupationActivity
@model
@auth(rules: [
{ allow: owner },
{ allow: public, operations: [read] }])
@key(name: "orderBy", fields: ["listOrder"])
{
id: ID!,
description: String!,
listOrder: Int!
}
type DietaryRequirement
@model
@auth(rules: [
{ allow: owner },
{ allow: public, operations: [read] }])
@key(name: "orderBy", fields: ["listOrder"])
{
id: ID!,
description: String!,
listOrder: Int!
}`
Hi @tappready, I have tried your schema in this sample.
[]
(error is Supplied AttributeValue is empty, must contain exactly one of the supported datatypes
). When constructing a UserProfile without setting anything for weightHistory, bmiHistory, favouriteFood then it will by default set it to []
. There is an issue being tracked here that is related to a service side bug: https://github.com/aws-amplify/amplify-cli/issues/4708 the current workaround is to set the fields to nil if not setting any data. For example:
let userProfile = UserProfile(dietryRequirments: nil, weightHistory: nil, bmiHistory: nil, favouriteFood: nil)
Amplify.DataStore.save(userProfile) { (result) in
switch result {
case .success(let savedModel):
print("Success!")
self.message = "userProfile \(savedModel)"
case .failure(let error):
self.message = "Error \(error)"
print(self.message)
}
}
By doing this, I was able to see the data persist in DynamoDB.
amplifyconfiguration.json
contains for the API using "authorizationType": "AMAZON_COGNITO_USER_POOLS"
Amplify.Auth.signIn
. If the sync engine has failed all it's attempts to establish the subscriptions, then even after signing in, DataStore will not try establishing the subscriptions again until a DataStore operation is triggered (ie. DataStore.save/query/etc..). I noticed that there is no column linking the model to the congnito user? is this correct?
That is correct, the owner field is added as a DynamoDB column and used by the AppSync service. If you'd like this field synchronized in the local store, you can add it as an optional field on the Model itself.
type UserProfile
@model(timestamps:{createdAt: "createdOn", updatedAt: "updatedOn"})
@auth(rules: [{ allow: owner }])
{
id: ID!,
// ....
owner: String
}
When saving the UserProfile, you can leave the owner field empty when creating the model instance
HI @lawmicha thank you again for you reply. I have not managed to get your new suggestions tried and tested as I am facing anew issue with 'Resource is not in the state stackUpdateComplete' when running amplify push.
HI @lawmicha thank you again for you reply. I have not managed to get your new suggestions tried and tested as I am facing anew issue with 'Resource is not in the state stackUpdateComplete' when running amplify push.
If it is a new app with data that you're okay with deleting and starting new, you can run amplify delete
and recreate from scratch. You can also open an issue over in Amplify CLI repo with additional context about the error you are getting
Hi @lawmicha, in the end I did have to to delete/remove the api and start over (no big deal).
Regarding the actual issue I followed you advice and still no luck. I sign up a new user sign that user In and save the UserProfile model and still nothing is pushed to the cloud (DynamoDB) this is snippet of my sign up code
AuthFunctions.signUp(username: emailValue, password: passwordValue, email: emailValue, completion: {(result) -> Void in
switch result {
case .success(let signUpResult):
AuthFunctions.fetchCurrentAuthSession(completion: {(result, error) -> Void in
if result?.isSignedIn ?? false {
self.saveUserProfile(signUpResult: signUpResult)
} else {
AuthFunctions.signIn(username: emailValue, password: passwordValue, completion: { signedIn, error -> Void in
if signedIn {
self.saveUserProfile(signUpResult: signUpResult)
}
})
}
})
case .failure(let error):
self.logger?.log(category: .app, message: "\(error.underlyingError!)")
self.removeSpinnerView()
}
func saveUserProfile(signUpResult: AuthSignUpResult) {
ModelHandler.save(model: self.appDelegate.currentUser!, completion: { result, error -> Void in
self.removeSpinnerView()
if case let .confirmUser(deliveryDetails, _) = signUpResult.nextStep {
self.deliveryDetails = deliveryDetails
self.logger?.log(category: .app, message: "Delivery details \(String(describing: deliveryDetails))")
DispatchQueue.main.async {
self.performSegue(withIdentifier: self.confirmSignUpSegueIdentifier, sender: self)
}
} else {
self.logger?.log(category: .app, message: "SignUp Complete")
DispatchQueue.main.async {
self.performSegue(withIdentifier: self.signUpCompleteSegueIdentifier, sender: self)
}
}
})
}
Ps I have placed the datastore methods in a custom Handler class like so
public static func save<M>(model: M, completion: @escaping (Bool, DataStoreError?) -> Void) where M : Model {
Amplify.DataStore.save(model) {
switch $0 {
case .success:
self.logger?.log(category: .database, message: "Saved Model:- \(model.modelName)")
completion(true, nil)
case .failure(let error):
self.logger?.log(category: .database, message: "Error saving:- \(error.localizedDescription)")
completion(false, error)
}
}
}
Appart from a novice error on my part not using
DispatchQueue.main.async
correctly I get the following logs
2020-07-24 10:57:39.477077+0100 MyBodyBud[2864:92094] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:39.477208+0100 MyBodyBud[2864:92094] [Client] Updating selectors after delegate addition failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:39.477335+0100 MyBodyBud[2864:92097] [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:39.477705+0100 MyBodyBud[2864:92097] [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:39.477737+0100 MyBodyBud[2864:92094] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:39.478047+0100 MyBodyBud[2864:92097] [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:39.478077+0100 MyBodyBud[2864:92094] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:39.481712+0100 MyBodyBud[2864:92094] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:39.481808+0100 MyBodyBud[2864:92094] [Client] Updating selectors after delegate removal failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:40.386476+0100 MyBodyBud[2864:92094] [app] [com.apple.root.default-qos] [AuthFunctions.swift:37 fetchCurrentAuthSession(completion:)] > Is user signed in - false
2020-07-24 10:57:40.395722+0100 MyBodyBud[2864:92094] [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:40.395783+0100 MyBodyBud[2864:92093] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:40.395942+0100 MyBodyBud[2864:92093] [Client] Updating selectors after delegate addition failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:40.396361+0100 MyBodyBud[2864:92094] [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:40.396394+0100 MyBodyBud[2864:92093] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:40.396942+0100 MyBodyBud[2864:92094] [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:40.397006+0100 MyBodyBud[2864:92093] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:40.397948+0100 MyBodyBud[2864:92093] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:40.398079+0100 MyBodyBud[2864:92093] [Client] Updating selectors after delegate removal failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
=================================================================
Main Thread Checker: UI API called on a background thread: -[UIApplication delegate]
PID: 2864, TID: 92094, Thread name: (none), Queue name: com.apple.root.default-qos, QoS: 0
Backtrace:
4 MyBodyBud 0x000000010f4c9f1d $s9MyBodyBud12ModelHandlerC4save5model10completionyx_ySb_ypSgtct7Amplify0D0RzlFZ + 205
5 MyBodyBud 0x000000010f548fd3 $s9MyBodyBud20SignUpViewControllerC15saveUserProfile04signE6Resulty7Amplify04AuthdeL0V_tF + 547
6 MyBodyBud 0x000000010f548d96 $s9MyBodyBud20SignUpViewControllerC02dodE0yyFys6ResultOy7Amplify04AuthdeI0VAG0K5ErrorOGcfU_yAG0K7Session_pSg_AKSgtcfU_ySb_0J7Plugins010AWSCognitokL0OSgtcfU_ + 198
7 MyBodyBud 0x000000010f5030eb $s9MyBodyBud13AuthFunctionsC6signIn8username8password10completionySS_SSySb_14AmplifyPlugins010AWSCognitoD5ErrorOSgtctFZys6ResultOy0K00d4SigngO0VAN0dN0OGcfU_ + 363
8 AmplifyPlugins 0x0000000110dfd994 $ss6ResultOy7Amplify010AuthSignInA0VAC0C5ErrorOGIegg_AHIegn_TR + 52
9 Amplify 0x0000000110a6c005 $s7Amplify0A9OperationC9subscribe14resultListenerAA16UnsubscribeTokenVys6ResultOyq_q0_Gc_tFyAA10HubPayloadVcfU_ + 917
10 Amplify 0x0000000110a6c24c $s7Amplify0A9OperationC9subscribe14resultListenerAA16UnsubscribeTokenVys6ResultOyq_q0_Gc_tFyAA10HubPayloadVcfU_TA + 92
11 Amplify 0x0000000110b42877 $s7Amplify16SerialDispatcherV8dispatch2toySayAA16FilteredListenerVG_tFyycfU_ + 631
12 Amplify 0x0000000110a553d0 $sIeg_IeyB_TR + 48
13 libdispatch.dylib 0x00000001114ebdf0 _dispatch_call_block_and_release + 12
14 libdispatch.dylib 0x00000001114ecd64 _dispatch_client_callout + 8
15 libdispatch.dylib 0x00000001114ef20b _dispatch_queue_override_invoke + 1022
16 libdispatch.dylib 0x00000001114fe29a _dispatch_root_queue_drain + 351
17 libdispatch.dylib 0x00000001114feba4 _dispatch_worker_thread2 + 132
18 libsystem_pthread.dylib 0x00007fff5141f9f7 _pthread_wqthread + 220
19 libsystem_pthread.dylib 0x00007fff5141eb77 start_wqthread + 15
2020-07-24 10:57:40.469094+0100 MyBodyBud[2864:92094] [reports] Main Thread Checker: UI API called on a background thread: -[UIApplication delegate]
PID: 2864, TID: 92094, Thread name: (none), Queue name: com.apple.root.default-qos, QoS: 0
Backtrace:
4 MyBodyBud 0x000000010f4c9f1d $s9MyBodyBud12ModelHandlerC4save5model10completionyx_ySb_ypSgtct7Amplify0D0RzlFZ + 205
5 MyBodyBud 0x000000010f548fd3 $s9MyBodyBud20SignUpViewControllerC15saveUserProfile04signE6Resulty7Amplify04AuthdeL0V_tF + 547
6 MyBodyBud 0x000000010f548d96 $s9MyBodyBud20SignUpViewControllerC02dodE0yyFys6ResultOy7Amplify04AuthdeI0VAG0K5ErrorOGcfU_yAG0K7Session_pSg_AKSgtcfU_ySb_0J7Plugins010AWSCognitokL0OSgtcfU_ + 198
7 MyBodyBud 0x000000010f5030eb $s9MyBodyBud13AuthFunctionsC6signIn8username8password10completionySS_SSySb_14AmplifyPlugins010AWSCognitoD5ErrorOSgtctFZys6ResultOy0K00d4SigngO0VAN0dN0OGcfU_ + 363
8 AmplifyPlugins 0x0000000110dfd994 $ss6ResultOy7Amplify010AuthSignInA0VAC0C5ErrorOGIegg_AHIegn_TR + 52
9 Amplify 0x0000000110a6c005 $s7Amplify0A9OperationC9subscribe14resultListenerAA16UnsubscribeTokenVys6ResultOyq_q0_Gc_tFyAA10HubPayloadVcfU_ + 917
10 Amplify 0x0000000110a6c24c $s7Amplify0A9OperationC9subscribe14resultListenerAA16UnsubscribeTokenVys6ResultOyq_q0_Gc_tFyAA10HubPayloadVcfU_TA + 92
11 Amplify 0x0000000110b42877 $s7Amplify16SerialDispatcherV8dispatch2toySayAA16FilteredListenerVG_tFyycfU_ + 631
12 Amplify 0x0000000110a553d0 $sIeg_IeyB_TR + 48
13 libdispatch.dylib 0x00000001114ebdf0 _dispatch_call_block_and_release + 12
14 libdispatch.dylib 0x00000001114ecd64 _dispatch_client_callout + 8
15 libdispatch.dylib 0x00000001114ef20b _dispatch_queue_override_invoke + 1022
16 libdispatch.dylib 0x00000001114fe29a _dispatch_root_queue_drain + 351
17 libdispatch.dylib 0x00000001114feba4 _dispatch_worker_thread2 + 132
18 libsystem_pthread.dylib 0x00007fff5141f9f7 _pthread_wqthread + 220
19 libsystem_pthread.dylib 0x00007fff5141eb77 start_wqthread + 15
2020-07-24 10:57:41.585627+0100 MyBodyBud[2864:92094] [database] [com.apple.root.default-qos] [BaseDataStoreModelHandler.swift:33 save(model:completion:)] > Saved Model:- UserProfile
2020-07-24 10:57:41.586260+0100 MyBodyBud[2864:92094] [app] [com.apple.root.default-qos] [SignUpViewController.swift:222 saveUserProfile(signUpResult:)] > Delivery details Optional(Amplify.AuthCodeDeliveryDetails(destination: Amplify.DeliveryDestination.email(Optional("s***@i***.com")), attributeKey: Optional(Amplify.AuthUserAttributeKey.email)))
2020-07-24 10:57:41.780647+0100 MyBodyBud[2864:92093] [AXRuntimeCommon] Unknown client: MyBodyBud
2020-07-24 10:57:44.625436+0100 MyBodyBud[2864:90154] Can't find keyplane that supports type 4 for keyboard iPhone-PortraitTruffle-NumberPad; using 25683_PortraitTruffle_iPhone-Simple-Pad_Default
2020-07-24 10:57:49.252647+0100 MyBodyBud[2864:92102] [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:49.252723+0100 MyBodyBud[2864:92096] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:49.252888+0100 MyBodyBud[2864:92096] [Client] Updating selectors after delegate addition failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:49.253357+0100 MyBodyBud[2864:92102] [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:49.253399+0100 MyBodyBud[2864:92096] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:49.253775+0100 MyBodyBud[2864:92102] [Client] Synchronous remote object proxy returned error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:49.253832+0100 MyBodyBud[2864:92096] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:49.259184+0100 MyBodyBud[2864:92096] [Client] Updating selectors failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:49.259334+0100 MyBodyBud[2864:92096] [Client] Updating selectors after delegate removal failed with: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated." UserInfo={NSDebugDescription=The connection to service on pid 0 named com.apple.commcenter.coretelephony.xpc was invalidated.}
2020-07-24 10:57:49.349012+0100 MyBodyBud[2864:92096] [app] [com.apple.root.default-qos] [AuthFunctions.swift:93 confirmSignUp(for:with:completion:)] > Confirm signUp succeeded
2020-07-24 10:58:01.744503+0100 MyBodyBud[2864:92102] [RemoteSyncEngine] pauseSubscriptions()
2020-07-24 10:58:01.745047+0100 MyBodyBud[2864:92102] [RemoteSyncEngine] pauseMutations()
2020-07-24 10:58:01.745328+0100 MyBodyBud[2864:92102] [RemoteSyncEngine] clearStateOutgoingMutations(storageAdapter:)
2020-07-24 10:58:01.746235+0100 MyBodyBud[2864:92102] [RemoteSyncEngine] initializeSubscriptions(api:storageAdapter:)
2020-07-24 10:58:01.749473+0100 MyBodyBud[2864:92102] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received subscription: PassthroughSubject
2020-07-24 10:58:01.751910+0100 MyBodyBud[2864:92102] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received subscription: PassthroughSubject
2020-07-24 10:58:01.753915+0100 MyBodyBud[2864:92102] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received subscription: PassthroughSubject
2020-07-24 10:58:01.755665+0100 MyBodyBud[2864:92102] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received subscription: PassthroughSubject
2020-07-24 10:58:01.757913+0100 MyBodyBud[2864:92102] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received subscription: PassthroughSubject
2020-07-24 10:58:01.788760+0100 MyBodyBud[2864:93570] Connecting to url ...
2020-07-24 10:58:01.974833+0100 MyBodyBud[2864:93570] WebsocketDidConnect
2020-07-24 10:58:01.974905+0100 MyBodyBud[2864:93570] WebsocketDidConnect, sending init message...
2020-07-24 10:58:01.974977+0100 MyBodyBud[2864:93570] Validating connection
2020-07-24 10:58:01.975064+0100 MyBodyBud[2864:93570] WebsocketDidReceiveMessage - {"payload":{"errors":[{"message":"Both, the \"header\", and the \"payload\" query string parameters are missing","errorCode":400}]},"type":"connection_error"}
2020-07-24 10:58:01.975424+0100 MyBodyBud[2864:93570] The data couldn’t be read because it isn’t in the correct format.
2020-07-24 10:58:01.975606+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.975884+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.976157+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.976393+0100 MyBodyBud[2864:93573] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received completion: failure(DataStoreError: subscription item event failed with error
Caused by:
APIError: subscription item event failed with error
Caused by:
jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil)))))
2020-07-24 10:58:01.976412+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.976549+0100 MyBodyBud[2864:93576] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received completion: failure(DataStoreError: subscription item event failed with error
Caused by:
APIError: subscription item event failed with error
Caused by:
jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil)))))
2020-07-24 10:58:01.978907+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.979004+0100 MyBodyBud[2864:93576] [AWSModelReconciliationQueue] receiveCompletion: error: DataStoreError: subscription item event failed with error
Caused by:
APIError: subscription item event failed with error
Caused by:
jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil))))
2020-07-24 10:58:01.979066+0100 MyBodyBud[2864:93573] [AWSModelReconciliationQueue] receiveCompletion: error: DataStoreError: subscription item event failed with error
Caused by:
APIError: subscription item event failed with error
Caused by:
jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil))))
2020-07-24 10:58:01.979145+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.979391+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.979396+0100 MyBodyBud[2864:93570] Unsubscribe - A512DA38-CEFB-4B7C-9722-A65A10D92B75
2020-07-24 10:58:01.979542+0100 MyBodyBud[2864:93570] Unsubscribe - 8F6DB92E-81ED-4256-944A-C5D8FCFD5FC1
2020-07-24 10:58:01.979636+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.979674+0100 MyBodyBud[2864:93570] Unsubscribe - 8F53B028-97C5-4E90-B5BA-71A34CE5B7C0
2020-07-24 10:58:01.979862+0100 MyBodyBud[2864:93570] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received completion: finished
2020-07-24 10:58:01.979892+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.980000+0100 MyBodyBud[2864:93570] Unsubscribe - EE43E683-61EC-4DFE-B8E0-653C890EBF50
2020-07-24 10:58:01.980238+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.980263+0100 MyBodyBud[2864:92102] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received completion: failure(DataStoreError: subscription item event failed with error
Caused by:
APIError: subscription item event failed with error
Caused by:
jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil)))))
2020-07-24 10:58:01.980357+0100 MyBodyBud[2864:93570] Unsubscribe - 4EDC0957-5E19-4E4C-9C15-BFF7C0E7C585
2020-07-24 10:58:01.980504+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.980556+0100 MyBodyBud[2864:93570] Unsubscribe - 74E09E02-9454-4E06-B9C2-15D8EF6BCB36
2020-07-24 10:58:01.980562+0100 MyBodyBud[2864:92102] [AWSModelReconciliationQueue] receiveCompletion: error: DataStoreError: subscription item event failed with error
Caused by:
APIError: subscription item event failed with error
Caused by:
jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil))))
2020-07-24 10:58:01.980675+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.980690+0100 MyBodyBud[2864:93570] Unsubscribe - 6E60FA8E-53F7-4111-8975-D60A9E4447E9
2020-07-24 10:58:01.980911+0100 MyBodyBud[2864:93570] Unsubscribe - 0A5297D8-7744-4BA0-A900-AA3A684CBF7F
2020-07-24 10:58:01.980934+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.981026+0100 MyBodyBud[2864:93572] Self is nil, listener is not called.
2020-07-24 10:58:01.981034+0100 MyBodyBud[2864:93570] Unsubscribe - 3F469A96-DB86-43EC-AD35-1AF56DA23604
2020-07-24 10:58:01.981171+0100 MyBodyBud[2864:93570] Unsubscribe - EC9B72F2-B917-47B2-8FD8-D617F7DDA339
2020-07-24 10:58:01.981195+0100 MyBodyBud[2864:93572] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
2020-07-24 10:58:01.981282+0100 MyBodyBud[2864:93570] Unsubscribe - F25DA6DA-41FC-4FDF-BC0C-974258480D53
2020-07-24 10:58:01.981412+0100 MyBodyBud[2864:93570] Unsubscribe - BFF33920-72D9-4FF2-B4B8-CA0B39655526
2020-07-24 10:58:01.981640+0100 MyBodyBud[2864:93570] Unsubscribe - CE7960CF-686D-4534-B097-D05773EEB6AD
2020-07-24 10:58:01.981705+0100 MyBodyBud[2864:93598] [IncomingAsyncSubscriptionEventToAnyModelMapper] Received completion: failure(DataStoreError: subscription item event failed with error
Caused by:
APIError: subscription item event failed with error
Caused by:
jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil)))))
Thanks for your patience with this. The errors that I see above is related to the sync engine's subscriptions failing to start. Do they continue to fail even after user signs in and you perform the DataStore.save operation? I think what's missing here might be alignment on the provisioning steps. Can you provide the steps you took to provisioned the API?
Conflict resolution enabled API
Did you enable conflict resolution for the API? if you haven't, conflict resolution is required for using DataStore and can be enabled afterwards by running amplify update api
and "Enable for DataStore", then amplify push
.
Cognito Auth as primary auth mode
DId you select cognito auth as primary and then API Key as additional? You can verify the set-up with amplifyconfiguration.json
, it should contain for the API using "authorizationType": "AMAZON_COGNITO_USER_POOLS" which represents the primary auth mode. amplify console api
will open the AppSync console and then you can check in the Settings that there the additional auth mode is API Key
Amplify configuration Do you have the same or similar code that configures Amplify and related plugins?
Subscriptions failing and succeeding after sign In Subscriptions are expected to fail since the user is required to be authenticated, you can try: signing in, then restarting the app. the session should be persisted and then the subscription errors should go away. This check is the same as making a DataStore operation without re-running the app which will attempt to restart the sync engine.
Bug workaround: Set collection parameters to nil
Passing in []
or not passing in any value for collections will default to []
and causeSupplied AttributeValue is empty, must contain exactly one of the supported datatypes
. Existing bug here
Thanks for your patience with this. The errors that I see above is related to the sync engine's subscriptions failing to start. Do they continue to fail even after user signs in and you perform the DataStore.save operation? I think what's missing here might be alignment on the provisioning steps. Can you provide the steps you took to provisioned the API?
I cannot remember every option I selected perhaps you can advise on the proper way to fully remove the amplify from my project and the steps that I should take to provision the API. (if the bellow answers are all correct and acceptable)
Conflict resolution enabled API Did you enable conflict resolution for the API? if you haven't, conflict resolution is required for using DataStore and can be enabled afterwards by running
amplify update api
and "Enable for DataStore", thenamplify push
.
I have configured Auto Merge
Cognito Auth as primary auth mode DId you select cognito auth as primary and then API Key as additional? You can verify the set-up with
amplifyconfiguration.json
, it should contain for the API using "authorizationType": "AMAZON_COGNITO_USER_POOLS" which represents the primary auth mode.amplify console api
will open the AppSync console and then you can check in the Settings that there the additional auth mode is API Key Cognito is my primary auth option and API key is my secondaryAmplify configuration Do you have the same or similar code that configures Amplify and related plugins?
Yes
do {
Amplify.Logging.logLevel = {
#if DEBUG
return .debug
#else
return .error
#endif
}()
let apiPlugin = AWSAPIPlugin(modelRegistration: AmplifyModels())
let dataStorePlugin = AWSDataStorePlugin(modelRegistration: AmplifyModels())
try Amplify.add(plugin: AWSCognitoAuthPlugin())
try Amplify.add(plugin: apiPlugin)
try Amplify.add(plugin: dataStorePlugin)
try Amplify.configure()
logger?.log(category: .app, message: "Initialized Amplify")
} catch {
logger?.log(category: .app, message: "Failed to initialize Amplify with \(error)")
return false
}
Subscriptions failing and succeeding after sign In Subscriptions are expected to fail since the user is required to be authenticated, you can try: signing in, then restarting the app. the session should be persisted and then the subscription errors should go away. This check is the same as making a DataStore operation without re-running the app which will attempt to restart the sync engine.
Ok so are you suggesting calling save after the users verification has been confirmed? In my previous comment I show that I call signIn before calling save and save is called within the completion block. Should the auth engine not have signed in the user if verification was needed?
Bug workaround: Set collection parameters to
nil
Passing in[]
or not passing in any value for collections will default to[]
and causeSupplied AttributeValue is empty, must contain exactly one of the supported datatypes
. Existing bug here
I have catered for this
if (newUserProfile?.weightHistory?.isEmpty) != nil {
newUserProfile?.weightHistory = nil
}
if (newUserProfile?.bmiHistory?.isEmpty) != nil {
newUserProfile?.bmiHistory = nil
}
if (newUserProfile?.favouriteFood?.isEmpty) != nil {
newUserProfile?.favouriteFood = nil
}
@lawmicha
Latest update I fully removed and delete the api and now get the following error when appearing to list a model that is currently only available in the cloud
2020-08-10 22:43:13.315945+0100 MyBodyBud[9594:205267] [AWSModelReconciliationQueue] receiveCompletion: error: DataStoreError: subscription item event failed with error
Caused by:
APIError: subscription item event failed with error
Caused by:
jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil))))
I was attempting to list the following model while not signed in
type ActivityLevel
@model
@auth(rules: [
{ allow: owner },
{ allow: public, operations: [read] }])
@key(name: "orderBy", fields: ["listOrder"])
{
id: ID!,
description: String!,
listOrder: Int!
}
Bellow is the setup (I have masked sensitive name with ****)
********@********-MBP ******** % amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project ********
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building ios
Using default provider awscloudformation
For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html
? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use ********
Adding backend environment dev to AWS Amplify Console app: ********
⠴ Initializing project in the cloud...
CREATE_IN_PROGRESS AuthRole AWS::IAM::Role Mon Aug 10 2020 15:01:35 GMT+0100 (British Summer Time) Resource creation Initiated
CREATE_IN_PROGRESS UnauthRole AWS::IAM::Role Mon Aug 10 2020 15:01:35 GMT+0100 (British Summer Time) Resource creation Initiated
CREATE_IN_PROGRESS DeploymentBucket AWS::S3::Bucket Mon Aug 10 2020 15:01:35 GMT+0100 (British Summer Time)
CREATE_IN_PROGRESS AuthRole AWS::IAM::Role Mon Aug 10 2020 15:01:35 GMT+0100 (British Summer Time)
CREATE_IN_PROGRESS UnauthRole AWS::IAM::Role Mon Aug 10 2020 15:01:34 GMT+0100 (British Summer Time)
CREATE_IN_PROGRESS amplify-********-dev-150129 AWS::CloudFormation::Stack Mon Aug 10 2020 15:01:30 GMT+0100 (British Summer Time) User Initiated
⠦ Initializing project in the cloud...
CREATE_IN_PROGRESS DeploymentBucket AWS::S3::Bucket Mon Aug 10 2020 15:01:36 GMT+0100 (British Summer Time) Resource creation Initiated
⠧ Initializing project in the cloud...
CREATE_COMPLETE UnauthRole AWS::IAM::Role Mon Aug 10 2020 15:01:50 GMT+0100 (British Summer Time)
⠦ Initializing project in the cloud...
CREATE_COMPLETE AuthRole AWS::IAM::Role Mon Aug 10 2020 15:01:51 GMT+0100 (British Summer Time)
⠴ Initializing project in the cloud...
CREATE_COMPLETE amplify-********-dev-150129 AWS::CloudFormation::Stack Mon Aug 10 2020 15:01:59 GMT+0100 (British Summer Time)
CREATE_COMPLETE DeploymentBucket AWS::S3::Bucket Mon Aug 10 2020 15:01:56 GMT+0100 (British Summer Time)
✔ Successfully created initial AWS cloud resources for deployments.
✔ Initialized provider successfully.
Initialized your environment successfully.
Your project has been successfully initialized and connected to the cloud!
Some next steps:
"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify add <category>" will allow you to add features like user login or a backend API
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify console" to open the Amplify Console and view your project status
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
Pro tip:
Try "amplify add api" to create a backend API and then "amplify publish" to deploy everything
********@********-MBP ******** % amplify add api
? Please select from one of the below mentioned services: GraphQL
? Provide API name: ********
? Choose the default authorization type for the API Amazon Cognito User Pool
Using service: Cognito, provided by: awscloudformation
The current configured provider is Amazon Cognito.
Do you want to use the default authentication and security configuration? Default configuration
Warning: you will not be able to edit these selections.
How do you want users to be able to sign in? Email or Phone Number
Do you want to configure advanced settings? Yes, I want to make some additional changes.
Warning: you will not be able to edit these selections.
What attributes are required for signing up? Email, Phone Number (This attribute is not supported by Facebook, Login With Amazon.)
Do you want to enable any of the following capabilities?
Successfully added auth resource
? Do you want to configure advanced settings for the GraphQL API Yes, I want to make some additional changes.
? Configure additional auth types? Yes
? Choose the additional authorization types you want to configure for the API API key
API key configuration
? Enter a description for the API key: ********APIKey
? After how many days from now the API key should expire (1-365): 7
? Configure conflict detection? Yes
? Select the default resolution strategy Auto Merge
? Do you have an annotated GraphQL schema? No
? Choose a schema template: Objects with fine-grained access control (e.g., a project management app with owner-based authorization)
GraphQL schema compiled successfully.
Edit your schema at ../schema.graphql or place .graphql files in a directory at ../schema
? Do you want to edit the schema now? No
Successfully added resource ******** locally
Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
********@********-MBP ******** % amplify push
Hi @tappready, sorry for the delay. For what it's worth, there has been quite some work done on DataStore for using the auth directive and it should be more stable, however i noticed with your schema it is using multi-auth set up for the model. The missing feature is multi-auth support so your app will continue to function against the primary auth mode which is user pools (that is what you have correctly configured) but when the user is not signed in, it will not fall back to the API key as the auth mode (this is the missing multi-auth feature).
I followed your provisioning steps with a few notes here
amplify console auth
and chose user pool, created a user with email as username.amplify console api
and chose GraphQL, went to the queries tab and sign in with the user, confirmed and updated the password.import SwiftUI
import Amplify
import Combine
struct ContentView: View {
var subscriber: AnyCancellable?
init() {
subscriber = Amplify.DataStore.publisher(for: ActivityLevel.self).sink { (completion) in
print(completion)
} receiveValue: { (mutationEvent) in
print("Got event back: \(mutationEvent)")
}
}
func signIn(username: String, password: String) {
Amplify.Auth.signIn(username: username, password: password) { result in
switch result {
case .success:
print("Sign in succeeded")
case .failure(let error):
print("Sign in failed \(error)")
}
}
}
var body: some View {
VStack {
Button("Sign in") {
signIn(username: "mlaw135@gmail.com", password: "password")
}
Button("DataStore call") {
let activityLevel = ActivityLevel(description: "description", listOrder: 1)
Amplify.DataStore.save(activityLevel) { (result) in
switch result {
case .success(let result):
print("Save successful \(result)")
case .failure(let error):
print("DataStore save failed with \(error)")
}
}
}
}
}
}
I ran this on two simulators, and clicked on Sign In on both. Using the one without the debugger attached, I clicked on the API call to save data to the local store and it synced to the cloud, triggering the subscriptions on the app with the debugger attached.
I also noticed that if the user is not signed in, datastore sync engine will fail, then when the user signs in, it may take some time for the retry to kick in to restart the subscriptions. You should be able to verify that the subscriptions are working by re-running the app on the simulator which will kick off the sync engine again. We're also working on a feature that will let you control when to start and stop the sync engine, which you can add in the successful callback of the sign in.
i'm going to mark this as feature request based on this schema:
type ActivityLevel
@model
@auth(rules: [
{ allow: owner },
{ allow: public, operations: [read] }])
@key(name: "orderBy", fields: ["listOrder"])
{
id: ID!,
description: String!,
listOrder: Int!
}
allow: owner
and allow: public
. When the user is not signed in, the data should be read-able using the API key as the secondary auth mode.@lawmicha is the conclusion that as of today we can't use Amplify.DataStore.publisher
until a user is signed in? I.e. we can't use that with IAM or the API Key sign in modes?
@lawmicha Thank you for your response I can see that there is documentation for DataStore.stop/start at but after an update of all my nom packages and pods I still cannot seem to see any implementation. Can you verify please.
@zeman-88 As I understood and experienced I belieave if your primary auth is Cognito User Pools (needed if you wish to configure authorization models) you are unable to use your secondary auth (API Key) to load models and that and auth rules of public is also not supported hence my need to use API Key
@tappready we release DataStore.start/stop
as part of Amplify 1.5.0. Were you able to leverage on the them to solve one of your issue?
@diegocstn Thank you for your response. Yes I was able to utilise DataStore.start/stop
and DataStoreSyncExpression
Can I ask if you have an update regarding support for auth on the model with multiple rules. allow: owner and allow: public. When the user is not signed in, the data should be read-able using the API key as the secondary auth mode.
Describe the bug I am attempting to get the real time sync to work with datastore with zero results even with a subscription the only callbacks I get is local mutations. Upon launch of the app I get the following output in the logs
APIError: subscription item event failed with error Caused by: jsonParse(nil, Optional(Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil)))) : [CodingKeys(stringValue: "type", intValue: nil)], debugDescription: "Cannot initialize RealtimeConnectionProviderResponseType from invalid String value connection_error", underlyingError: nil)))) 2020-06-28 12:02:25.214300+0100 MyBodyBud[2336:34582] The operation couldn’t be completed. (AppSyncRealTimeClient.ConnectionProviderError error 0.)
Some extra points: I do attempt to save a UserProfile entry (Model detailed bellow) and this successfully saves locally and the a mutation subscription fires locally but nothing is synced to the cloud. My cloud DynamoDB has the model DietaryRequirement populate with data but this data is not synced locally with datastore.
I am not sure what else I can provide anything else please ask.
Expected behavior I would expect data to sync with backend cloud
Environment(please complete the following information):
Device Information (please complete the following information):
Additional context
AppDelegate.swift
Extracts from my schema.graphql
type WeightHistory { weight: Float!, dateTime: AWSDateTime! } ... type DietaryRequirement @model @auth(rules: [{ allow: public, operations: [read] }]) @key(name: "orderBy", fields: ["listOrder"]) { id: ID!, description: String!, listOrder: Int! } ...