aws-amplify / aws-amplify/amplify-android

DataStore subscribes to non-existing mutations

Open
#1,594 3 comments 0 reactions 0 assignees View on GitHub
datastore feature-request
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.