amplify-android
amplify-android copied to clipboard
NullPointerException on isReadRestrictingStaticGroup when using dynamic group authorization
Before opening, please confirm:
- [X] I have searched for duplicate or closed issues and discussions.
Language and Async Model
Kotlin
Amplify Categories
DataStore
Gradle script dependencies
I'm not really sure. Dependencies are transient via amplify-flutter.
pubspec.yaml
amplify_flutter: ^0.2.8
amplify_api: ^0.2.8
amplify_datastore: ^0.2.8
Environment information
Welcome to Gradle 6.7!
Here are the highlights of this release:
- File system watching is ready for production use
- Declare the version of Java your build requires
- Java 15 support
For more details see https://docs.gradle.org/6.7/release-notes.html
------------------------------------------------------------
Gradle 6.7
------------------------------------------------------------
Build time: 2020-10-14 16:13:12 UTC
Revision: 312ba9e0f4f8a02d01854d1ed743b79ed996dfd3
Kotlin: 1.3.72
Groovy: 2.5.12
Ant: Apache Ant(TM) version 1.10.8 compiled on May 10 2020
JVM: 1.8.0_302 (Oracle Corporation 25.302-b08)
OS: Linux 5.13.19-2-MANJARO amd64
Please include any relevant guides or documentation you're referencing
https://docs.amplify.aws/cli/graphql-transformer/auth/#dynamic-group-authorization
Describe the bug
I'm trying to use Datastore via Amplify Flutter on a schema with a dynamic group authorization rule. After configuration the app immediately throws a NullPointerException
on isReadRestrictingStaticGroup
. I'm opening the issue in this repo because it seems to be coming from this codebase.
W/amplify:aws-datastore(14059): An error occurred on the remote ON_UPDATE subscription for model Todo
W/amplify:aws-datastore(14059): java.lang.NullPointerException: Attempt to invoke interface method 'boolean java.util.List.isEmpty()' on a null object reference
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.auth.AuthRuleRequestDecorator.isReadRestrictingStaticGroup(AuthRuleRequestDecorator.java:147)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.auth.AuthRuleRequestDecorator.decorate(AuthRuleRequestDecorator.java:103)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.AWSApiPlugin.buildSubscriptionOperation(AWSApiPlugin.java:628)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.AWSApiPlugin.subscribe(AWSApiPlugin.java:308)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.AWSApiPlugin.subscribe(AWSApiPlugin.java:288)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.ApiCategory.subscribe(ApiCategory.java:91)
W/amplify:aws-datastore(14059): at com.amplifyframework.datastore.appsync.AppSyncClient.subscription(AppSyncClient.java:332)
Reproduction steps (if applicable)
No response
Code Snippet
Repo with minimal repro (Flutter required)
Log output
I/amplify:flutter:api(14059): Added API plugin
I/amplify:aws-datastore(14059): Creating table: PersistentModelVersion
I/amplify:aws-datastore(14059): Creating table: LastSyncMetadata
I/amplify:aws-datastore(14059): Creating table: Todo
I/amplify:aws-datastore(14059): Creating table: PersistentRecord
I/amplify:aws-datastore(14059): Creating table: ModelMetadata
I/amplify:aws-datastore(14059): Creating index for table: PersistentRecord
I/amplify:flutter:datastore(14059): Unhandled DataStoreHubEvent: SUCCEEDED
I/amplify:flutter:datastore(14059): com.amplifyframework.core.category.CategoryInitializationResult@69374e1
I/amplify:aws-datastore(14059): Orchestrator lock acquired.
I/amplify:aws-datastore(14059): Orchestrator transitioning from STOPPED to SYNC_VIA_API
I/amplify:aws-datastore(14059): Starting to observe local storage changes.
I/amplify:aws-datastore(14059): Now observing local storage. Local changes will be enqueued to mutation outbox.
I/amplify:aws-datastore(14059): Setting currentState to LOCAL_ONLY
I/amplify:aws-datastore(14059): Setting currentState to SYNC_VIA_API
I/amplify:aws-datastore(14059): Starting API synchronization mode.
I/amplify:flutter:datastore(14059): Established a new stream form flutter com.amplifyframework.datastore.storage.sqlite.-$$Lambda$coxN3FV0myAqN-gpZfZvj7bzSOI@bb578af
I/amplify:aws-datastore(14059): Orchestrator lock released.
I/amplify:aws-datastore(14059): Starting processing subscription events.
W/amplify:aws-datastore(14059): An error occurred on the remote ON_UPDATE subscription for model Todo
W/amplify:aws-datastore(14059): java.lang.NullPointerException: Attempt to invoke interface method 'boolean java.util.List.isEmpty()' on a null object reference
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.auth.AuthRuleRequestDecorator.isReadRestrictingStaticGroup(AuthRuleRequestDecorator.java:147)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.auth.AuthRuleRequestDecorator.decorate(AuthRuleRequestDecorator.java:103)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.AWSApiPlugin.buildSubscriptionOperation(AWSApiPlugin.java:628)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.AWSApiPlugin.subscribe(AWSApiPlugin.java:308)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.aws.AWSApiPlugin.subscribe(AWSApiPlugin.java:288)
W/amplify:aws-datastore(14059): at com.amplifyframework.api.ApiCategory.subscribe(ApiCategory.java:91)
W/amplify:aws-datastore(14059): at com.amplifyframework.datastore.appsync.AppSyncClient.subscription(AppSyncClient.java:332)
amplifyconfiguration.json
{
"UserAgent": "aws-amplify-cli/2.0",
"Version": "1.0",
"api": {
"plugins": {
"awsAPIPlugin": {
"amplifyoidcissue": {
"endpointType": "GraphQL",
"endpoint": "https://xxxxxx.appsync-api.eu-west-1.amazonaws.com/graphql",
"region": "eu-west-1",
"authorizationType": "OPENID_CONNECT"
}
}
}
}
}
GraphQL Schema
type Todo @model @auth(rules: [
{ allow: owner, ownerField: "owner", provider: oidc, identityClaim: "sub" },
{ allow: groups, provider: oidc, groupsField: "groupsCanEdit", groupClaim: "groups", groups: [] },
{ allow: groups, provider: oidc, groupsField: "groupsCanAccess", groupClaim: "groups", operations: [read], groups: [] }
]) {
id: ID!
name: String!
description: String
groupsCanAccess: [String]!
groupsCanEdit: [String]!
owner: String
}
Additional information and screenshots
No response
I imagine it has something to do with a known limitation that is mentioned in the new documentation:
Known limitation: Real-time subscriptions are not supported for dynamic group authorization.
Nonetheless, pretty disappointing.
Hi @ObeA, what jwshyns has said above is correct, and agreed that this is a pretty disappointing user experience. In the immediate future this is not supported, but we are looking at ways to unblock use cases like this this year.
With this finally released for AppSync, https://aws.amazon.com/blogs/mobile/appsync-enhanced-filtering/ and with the CLI adding support soon: aws-amplify/amplify-category-api#389 what is the timeline for dynamic group support for subscriptions for android? Would making SyncExpressions server sided also make sense?
@djorgji Our plan for the functionality mentioned in that comment includes providing some mechanism to pass server-side sync metadata up from the client, but the DX for that and associated API changes haven't been designed yet from a DataStore perspective. We are, however, tracking that as part of our support model across Amplify for enhanced server-side filtering.
I believe this should remove the primary technical blocker to dynamic group subscription filtering, but will tag this to the project so we evaluate this use-case as part of the design process.
@alharris-at Thank you for the reply! I am excited for the update, it is validating our choice to pick AWS Amplify and stick out through the limitations. Ideally from a security, scalability and optimization perspective running dynamic group filtering, and running sync expressions (or a similar mechanism) in the backend, would be amazing. Please keep us updated.