amplify-swift: DataStore persistence not working
Describe the bug
While trying to maintain persistence in AWS DataStore by pushing to the cloud, Data is not persisted to AWS AppSync.
AMPLIFYCONFIGURATION.JSON
{
"UserAgent": "aws-amplify-cli/2.0",
"Version": "1.0",
"api": {
"plugins": {
"awsAPIPlugin": {
"equestlyride": {
"endpointType": "GraphQL",
"endpoint": "https://xxxxxx.appsync-api.us-east-1.amazonaws.com/graphql",
"region": "us-east-1",
"authorizationType": "AMAZON_COGNITO_USER_POOLS",
"apiKey": ""
}
}
}
},
"auth": {
"plugins": {
"awsCognitoAuthPlugin": {
"UserAgent": "aws-amplify/cli",
"Version": "0.1.0",
"IdentityManager": {
"Default": {}
},
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "us-east-1:e1890af2-49dd-4250-b9fc-xxxxxxxx",
"Region": "us-east-1"
}
}
},
"CognitoUserPool": {
"Default": {
"PoolId": "us-east-xxxxxx",
"AppClientId": "xxxxxx",
"Region": "us-east-1"
}
},
"Auth": {
"Default": {
"authenticationFlowType": "USER_SRP_AUTH",
"socialProviders": [],
"usernameAttributes": [
"EMAIL"
],
"signupAttributes": [
"EMAIL"
],
"passwordProtectionSettings": {
"passwordPolicyMinLength": 8,
"passwordPolicyCharacters": []
},
"mfaConfiguration": "OFF",
"mfaTypes": [
"SMS"
],
"verificationMechanisms": [
"EMAIL"
]
}
},
"AppSync": {
"Default": {
"ApiUrl": "https://xxxxxx.appsync-api.us-east-1.amazonaws.com/graphql",
"Region": "us-east-1",
"AuthMode": "AMAZON_COGNITO_USER_POOLS",
"ClientDatabasePrefix": "equestlyride_AMAZON_COGNITO_USER_POOLS"
},
"equestlyride_API_KEY": {
"ApiUrl": "https://xxxxxx.appsync-api.us-east-1.amazonaws.com/graphql",
"Region": "us-east-1",
"AuthMode": "API_KEY",
"ApiKey": "",
"ClientDatabasePrefix": "equestlyride_API_KEY"
}
}
}
}
}
}
APP DELEGATE SET UP
import Foundation
import SwiftUI
import Amplify
import AWSCognitoAuthPlugin
import AWSDataStorePlugin
import AWSAPIPlugin
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
try Amplify.add(plugin: AWSCognitoAuthPlugin())
try Amplify.add(plugin: AWSDataStorePlugin(modelRegistration: AmplifyModels()))
try Amplify.add(plugin: AWSAPIPlugin())
try Amplify.configure()
Amplify.DataStore.start{ (result) in
switch(result) {
case .success:
print("DataStore started")
case .failure(let error):
print("Error starting DataStore:\(error)")
}
}
print("Amplify configured with auth plugin")
print("Amplify configured with dataStore plugin")
print("Amplify configured with API plugin")
} catch {
print("Failed to initialize Amplify with \(error)")
}
return true
}
}
SCHEMA.GRAPHQL
# This "input" configures a global authorization rule to enable public access to
# all models in this schema. Learn more about authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules
# input AMPLIFY { globalAuthRule: AuthRule = { allow: public } } # FOR TESTING ONLY!
type User @model @auth(rules: [{ allow: owner }]) {
id: ID!
username: String!
firstName: String
lastName: String
subscriptionType: Int
rides: [Ride] @hasMany
calendarItems: [CalendarEvent] @hasMany
cartID : ID
cart: UserCart @hasOne (fields:["cartID"])
}
type Ride @model @auth(rules: [{ allow: owner }]) {
id: ID!
distance: Float!
duration: Int!
timestamp: AWSTimestamp!
locations: [Location] @hasMany(indexName: "fromRide", fields: ["id"])
}
type Location @model @auth(rules: [{ allow: owner }]) {
rideID: ID! @index(name: "fromRide")
latitude: Float!
longitude: Float!
timestamp: AWSTimestamp!
ride: Ride @belongsTo(fields: ["rideID"])
}
type CalendarEvent @model @auth(rules: [{ allow: owner }]){
id: ID!
title: String!
timestamp: AWSTimestamp!
}
type UserCart @model @auth(rules: [{ allow: owner }]){
id: ID!
products: [SelectedProducts]
}
type SelectedProducts{
id: ID!
variantID: String!
}
When writing to CalendarEvent, I implemented a publisher to notify when changes were made as per documentation as shown below
func subscribeToPosts() {
postsSubscription = Amplify.DataStore.publisher(for: CalendarEvent.self)
.sink {
if case let .failure(error) = $0 {
print("Subscription received error - \(error.localizedDescription)")
}
}
receiveValue: { changes in
// handle incoming changes
print("Subscription received mutation: \(changes)")
}
}
I then receive:
Subscription received mutation: MutationEvent(id: "BF9F8445-4E9D-4048-876E-32FCEA79505C", modelId: "31AA572E-AAB8-40D9-873D-FB155B9769CE", modelName: "CalendarEvent", json: "{\"id\":\"31AA572E-AAB8-40D9-873D-FB155B9769CE\",\"title\":\"Eeer\",\"timestamp\":1646795797}", mutationType: "create", createdAt: Amplify.Temporal.DateTime(foundationDate: 2022-03-09 03:16:41 +0000), version: nil, inProcess: false, graphQLFilterJSON: nil)
But later, when querying AWS AppSync, there are no items. I have also verified against DynamoDB. No items are persisted.
Steps To Reproduce
Code Snipets + configuration files provided above
Expected behavior
I expect persistence to backend
Amplify Framework Version
1.21.0
Amplify Categories
API, DataStore
Dependency manager
Swift PM
Swift version
5.0
CLI version
7.6.23
Xcode version
13.2.1 (13C100)
Relevant log output
Not applicable
Is this a regression?
No
Regression additional context
No response
Device
Iphone 12ProMax
iOS Version
15.3.1
Specific to simulators
No
Additional context
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 19 (8 by maintainers)
To further investigate the issue you are facing with Auth, I would need to ask some clarifying questions.
getCurrentUser,fetchAuthSession,signInandsignOut?logoutfails, is it blocking you from doing all other operations using amplify?Hi @carl0sLOL, what I meant by a user that needs to be confirmed is if your
signInAPI call returns aAuthSignInStepother thandone. In your case, you have done the correct flow to confirm the user that has signed up. I can also see the tokens in your logs, DataStore uses eitheraccessTokenoridTokenwhen constructing the request for AppSync that has UserPool auth enabled, when syncing the save’s. I checked my User Pools console and my app client also doesn’t have Cognito User Pool checked off under Enable Identity Providers so I feel that might not be what made it work. You can reduce this step down just starting DataStore to reduce the logging and further debug, ie.Please see the updated schema in https://github.com/aws-amplify/amplify-ios/issues/1673#issuecomment-1063496504 at the bottom, i’ve made an explicit belongs-to relationship from the CalendarEvent to the user. one directional has-many isn’t something fully tested/supported by DataStore on iOS at the moment. The field that is generated but not explicit in the schema
userCalendarItemsIdstores the userId which the calendarEvent belongs to