aws-amplify / aws-amplify/amplify-android
DataStore subscribes to non-existing mutations
- Dominant language
- Java
- Stars
- 287
- Forks
- 132
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 45
Description
### Before opening, please confirm:
- [x] I have [searched for duplicate or closed issues](https://github.com/aws-amplify/amplify-android/issues?q=is%3Aissue+) and [discussions](https://github.com/aws-amplify/amplify-android/discussions).
### Language and Async Model
Kotlin - Coroutines
### Amplify Categories
DataStore
### Gradle script dependencies
```groovy
implementation 'com.amplifyframework:core-kotlin:0.12.1'
implementation 'com.amplifyframework:aws-api:1.28.1'
implementation 'com.amplifyframework:aws-datastore:1.28.1'
implementation 'com.amplifyframework:aws-auth-cognito:1.28.1'
```
### Environment information
```
# Put output below this line
Build time: 2021-08-17 09:59:03 UTC
Revision: a773786b58bb28710e3dc96c4d1a7063628952ad
Kotlin: 1.5.21
Groovy: 3.0.8
Ant: Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM: 15.0.2 (Oracle Corporation 15.0.2+7-27)
```
### Please include any relevant guides or documentation you're referencing
_No response_
### Describe the bug
If we create a GraphQL schema with some `@model`s, and disable some of the default mutations, `DataStore` category still tries to subscribe on the disabled mutations.
This behaviour leads to an error when performing any operation, because of the server rejecting the subscription.
### Reproduction steps (if applicable)
1. Create a schema similar to the one attached below
2. Try using DataStore to query something.
3. The attached error will be thrown
### Code Snippet
```kotlin
Amplify.DataStore.query(AnyOfMyModels::class).collect {}
```
### Log output
There is a `@model` called `PerformedBlockItem` in our schema.
When I query, regardless of the queried model type, a similar error to this is thrown:
```
E/amplify:aws-datastore: Failure encountered while attempting to start API sync.
GraphQLResponseException{message=Subscription error for PerformedBlockItem: [GraphQLResponse.Error{message='Validation error of type FieldUndefined: Field 'onCreatePerformedBlockItem' in type 'Subscription' is undefined @ 'onCreatePerformedBlockItem'', locations='null', path='null', extensions='null'}], errors=[GraphQLResponse.Error{message='Validation error of type FieldUndefined: Field 'onCreatePerformedBlockItem' in type 'Subscription' is undefined @ 'onCreatePerformedBlockItem'', locations='null', path='null', extensions='null'}], recoverySuggestion=See attached list of GraphQLResponse.Error objects.}
at com.amplifyframework.datastore.appsync.AppSyncClient.lambda$subscription$2(AppSyncClient.java:321)
at com.amplifyframework.datastore.appsync.AppSyncClient$$ExternalSyntheticLambda5.accept(Unknown Source:8)
at com.amplifyframework.api.aws.SubscriptionEndpoint$Subscription.dispatchNextMessage(SubscriptionEndpoint.java:414)
at com.amplifyframework.api.aws.SubscriptionEndpoint.notifySubscriptionData(SubscriptionEndpoint.java:248)
at com.amplifyframework.api.aws.SubscriptionEndpoint.access$700(SubscriptionEndpoint.java:61)
at com.amplifyframework.api.aws.SubscriptionEndpoint$AmplifyWebSocketListener.processJsonMessage(SubscriptionEndpoint.java:592)
at com.amplifyframework.api.aws.SubscriptionEndpoint$AmplifyWebSocketListener.onMessage(SubscriptionEndpoint.java:498)
```
### amplifyconfiguration.json
_No response_
### GraphQL Schema
This is the schema before compilation:
```graphql
type PerformedBlockItem @model(queries: null, mutations: null)
id: ID!
... other things
}
```
This also happens when mutations is not null but contains only some of the mutations.
After compilation, the schema's `Subscription` part doesn't contain any subscription for our model.
### Additional information and screenshots
As a workaround, I can let amplify generate all mutations (and all subscriptions), and block access to those I'm no interested in by permissions, but this is a really bad behavior I would like to avoid of course.
Code-wise:
I've seen in
https://github.com/aws-amplify/amplify-android/blob/ca1be4812651026631b94dc711ad1bedf2fda2ea/aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/SubscriptionProcessor.java#L119-L134
It creates requests for all subscriptions regardless of which mutation really exists.
I also saw the same behavior in Amplify for JS. Maybe it's intentional for some reason.
Anyway It would be great if we can discuss this or find a solution.
Contributor guide
Research direction
Start by reading aws-datastore/src/main/java/com/amplifyframework/datastore/syncengine/SubscriptionProcessor.java around lines 119-134, then trace how DataStore builds subscriptions for a schema with disabled mutations. Done means DataStore no longer attempts subscriptions absent from the compiled GraphQL Subscription type, and querying a model does not fail with the reported FieldUndefined error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, java, kotlin
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100