Description
Description
By following the Getting started instructions and setting up the datastore Cloud Feature at this page: https://docs.amplify.aws/lib/datastore/sync/q/platform/flutter/#setup-cloud-sync
We can read this line: "DataStore's cloud synchronization uses the API category behind the scenes. Therefore, the first step is to add the API plugin."
This leads people to believing that they can use the documentation at the linked page.
In the same manner, the Setup authorization rules page (at https://docs.amplify.aws/lib/datastore/setup-auth-rules/q/platform/flutter/ ) refers a few times to the AppSync cli page (at https://docs.amplify.aws/cli/graphql/authorization-rules/#per-user--owner-based-data-access ).
On this page, a section is name "Multi-user data access". I can attest that the code in this section will not work with Datastore, I suspect due to the limitation on subscription and multi-owner models.
I tried all possible configuration (transformer v1, removing multi auth, experimental pipeline, other feature flags, as a single model, etc) and all tests were done with an empty datastore. After working 3 days on this, I am convinced there is no way to have this working in a native way.
Having a documentation that is representative of the available feature is of paramount importance to us.
Note: While this could be framed as a bug in the datastore/appsync plugins for this specific example, this is a recurring theme with these two plugins. See #1566 (comment) for technical details.
Categories
- Analytics
- API (REST)
- API (GraphQL)
- Auth
- Authenticator
- DataStore
- Notifications (Push)
- Storage
Steps to Reproduce
- Follow the getting started instructions and create a new project
- Add auth (default settings without social + iam as secondary auth)
- Add api and datastore as per the documentation
- Add a multi-owner model
- Try to start the app.
Screenshots
Relevant Logs:
[ +45 ms] E/amplify:aws-datastore( 6140): Failure encountered while attempting to start API sync.
[ ] E/amplify:aws-datastore( 6140): DataStoreException{message=DataStore subscriptionProcessor failed to start., cause=GraphQLResponseException{message=Subscription error for Task: [GraphQLResponse.Error{message='Validation error of type UnknownArgument: Unknown field argument authors @ 'onCreateTask'', locations='null', path='null', extensions='null'}], errors=[GraphQLResponse.Error{message='Validation error of type UnknownArgument: Unknown field argument authors @ 'onCreateTask'', locations='null', path='null', extensions='null'}], recoverySuggestion=See attached list of GraphQLResponse.Error objects.}, recoverySuggestion=Check your internet.}
[ ] E/amplify:aws-datastore( 6140): at com.amplifyframework.datastore.syncengine.Orchestrator.lambda$startApiSync$3$com-amplifyframework-datastore-syncengine-Orchestrator(Orchestrator.java:306)
[ ] E/amplify:aws-datastore( 6140): at com.amplifyframework.datastore.syncengine.Orchestrator$$ExternalSyntheticLambda6.subscribe(Unknown Source:2)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.internal.operators.completable.CompletableCreate.subscribeActual(CompletableCreate.java:40)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.core.Completable.subscribe(Completable.java:2850)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.internal.operators.completable.CompletablePeek.subscribeActual(CompletablePeek.java:51)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.core.Completable.subscribe(Completable.java:2850)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.internal.operators.completable.CompletablePeek.subscribeActual(CompletablePeek.java:51)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.core.Completable.subscribe(Completable.java:2850)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.internal.operators.completable.CompletablePeek.subscribeActual(CompletablePeek.java:51)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.core.Completable.subscribe(Completable.java:2850)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.internal.operators.completable.CompletableSubscribeOn$SubscribeOnObserver.run(CompletableSubscribeOn.java:64)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.core.Scheduler$DisposeTask.run(Scheduler.java:614)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:65)
[ ] E/amplify:aws-datastore( 6140): at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:56)
[ ] E/amplify:aws-datastore( 6140): at java.util.concurrent.FutureTask.run(FutureTask.java:264)
[ ] E/amplify:aws-datastore( 6140): at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:307)
[ ] E/amplify:aws-datastore( 6140): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
[ ] E/amplify:aws-datastore( 6140): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
[ ] E/amplify:aws-datastore( 6140): at java.lang.Thread.run(Thread.java:1012)
[ ] E/amplify:aws-datastore( 6140): Caused by: GraphQLResponseException{message=Subscription error for Task: [GraphQLResponse.Error{message='Validation error of type UnknownArgument: Unknown field argument authors @ 'onCreateTask'', locations='null', path='null', extensions='null'}], errors=[GraphQLResponse.Error{message='Validation error of type UnknownArgument: Unknown field argument authors @ 'onCreateTask'', locations='null', path='null', extensions='null'}], recoverySuggestion=See attached list of GraphQLResponse.Error objects.}
Generated code:
input ModelSubscriptionTaskFilterInput {
content: ModelSubscriptionStringInput
and: [ModelSubscriptionTaskFilterInput]
or: [ModelSubscriptionTaskFilterInput]
_deleted: ModelBooleanInput
}
type Subscription {
onCreateTask(filter: ModelSubscriptionTaskFilterInput): Task @aws_subscribe(mutations: ["createTask"]) @aws_iam @aws_cognito_user_pools
onUpdateTask(filter: ModelSubscriptionTaskFilterInput): Task @aws_subscribe(mutations: ["updateTask"]) @aws_iam @aws_cognito_user_pools
onDeleteTask(filter: ModelSubscriptionTaskFilterInput): Task @aws_subscribe(mutations: ["deleteTask"]) @aws_iam @aws_cognito_user_pools
}
Code to replicate:
Future<void> configureAmplify() async {
// Add any Amplify plugins you want to use
final authPlugin = AmplifyAuthCognito();
// await Amplify.addPlugin(authPlugin);
// Add the following lines to your app initialization to add the DataStore plugin
final datastorePlugin = AmplifyDataStore(
modelProvider: ModelProvider.instance,
// Be sure to add the authModeStrategy
authModeStrategy: AuthModeStrategy.multiAuth,
);
// await Amplify.addPlugin(datastorePlugin);
final api = AmplifyAPI();
// You can use addPlugins if you are going to be adding multiple plugins
await Amplify.addPlugins([authPlugin, api, datastorePlugin]);
// await Amplify.addPlugins([authPlugin]);
// Once Plugins are added, configure Amplify
// Note: Amplify can only be configured once.
try {
await Amplify.configure(amplifyconfig);
} on AmplifyAlreadyConfiguredException {
safePrint("Tried to reconfigure Amplify; this can occur when your app restarts on Android.");
}
}
Platforms
- iOS
- Android
- Web
- macOS
- Windows
- Linux
Flutter Version
3.10.5
Amplify Flutter Version
1.2.0
Deployment Method
Amplify CLI
Schema
type Task @model @auth(rules: [{ allow: owner, ownerField: "authors" }]) {
content: String
authors: [String]
}