amplify-js: Datastore not working properly with owner @auth rule on React Native

Describe the bug I am not able to use Datastore in my Expo app because of a problem with the owner @auth rule in my schema. When my app is starting, Datastore is initializing and I get the following warning in the console:

[INFO] 31:40.933 Reachability - subscribing to reachability in React Native
[INFO] 31:40.970 Reachability - Notifying initial reachability state null
[INFO] 31:42.959 Reachability - Notifying reachability change true

[WARN] 31:43.842 DataStore - Sync error, subscription failed Connection failed: {"errors":[{"message":"Validation error of type MissingFieldArgument: Missing field argument owner @ 'onDeleteCall'"}]}
- node_modules/expo/build/environment/muteWarnings.fx.js:18:23 in warn
* [native code]:null in warn
* http://192.168.1.16:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:125761:12 in <unknown>
* http://192.168.1.16:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:125794:22 in <unknown>
- node_modules/@aws-amplify/datastore/lib-esm/datastore/datastore.js:659:35 in sync.start.subscribe$argument_0.error
- node_modules/zen-observable/lib/Observable.js:139:8 in notifySubscription
* http://192.168.1.16:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:129987:23 in onNotify
- node_modules/zen-observable/lib/Observable.js:239:11 in error
- node_modules/@aws-amplify/datastore/lib-esm/sync/index.js:141:56 in __generator$argument_1
* http://192.168.1.16:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:127369:27 in step
- node_modules/tslib/tslib.js:122:34 in <anonymous>
- node_modules/tslib/tslib.js:113:43 in rejected
- node_modules/promise/setimmediate/core.js:37:14 in tryCallOne
- node_modules/promise/setimmediate/core.js:123:25 in setImmediate$argument_0
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:146:14 in _callTimer
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:194:17 in _callImmediatesPass
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:458:30 in callImmediates
* [native code]:null in callImmediates
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:407:6 in __callImmediates
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:143:6 in __guard$argument_0
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:384:10 in __guard
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:142:17 in __guard$argument_0
* [native code]:null in flushedQueue
* [native code]:null in callFunctionReturnFlushedQueue

It looks like Datastore does not pass required owner attribute when it subscribes to changes.

To Reproduce

  1. In an Expo app, add an owner rule in your schema: @auth(rules: [{allow: owner}]).
  2. amplify push
  3. npm run amplify-modelgen or amplify codegen models
  4. npm start
  5. When using Datastore, you will see the warning in the console.

Expected behavior At least no warning in the console.

What is Configured? cli: @aws-amplify/cli@4.20.0 package.json:

"@aws-amplify/api": "^3.1.10",
"@aws-amplify/auth": "^3.2.7",
"@aws-amplify/core": "^3.2.7",
"@aws-amplify/datastore": "^2.1.0",

Thanks for your help.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 20 (5 by maintainers)

Most upvoted comments

Hi @manueliglesias

I have tried and it still does not work.

It seems to me that it still the early age of Datastore, specially with React Native (it was released a couple of months ago for React Native). I have tried to set up the Datastore in my app, and my conclusion is that as long as you have a simple schema, without @auth rules, it’s working well.

I have many types and @auth rules in my app schema. For now I managed to make the Datastore work with only one type.

For instance :

type Call
@model
@auth(rules: [
  {allow: owner}
  {allow: private, provider: iam}
])
{
  id: ID!
  owner: String
  duration: Int
}

This type does not work with Datastore and produce error above.

type Company
@model(subscriptions: {level: public})
@auth(rules: [
  {allow: public, operations: [read]},
  {allow: private, operations: [read]}
  {allow: private, provider: iam}
])
{
  id: ID!
  name: String!
}

This type works with the Datastore but I had to use a workaround to make it work. After generating models with amplify codegen models, I removed those lines in src/models/schema.js:

                  {
                    "type": "auth",
                    "properties": {
                        "rules": [
                            {
                                "allow": "public",
                                "operations": [
                                    "read"
                                ]
                            },
                            {
                                "allow": "private",
                                "operations": [
                                    "read"
                                ]
                            },
                            {
                                "allow": "private",
                                "provider": "iam"
                            }
                        ]
                    }
                }

It is weird that I have to do this to make it work.

Some update about this issue. I still cannot use the DataStore with the @auth rules of my project.

I have the following schema:

type Company
  @model(subscriptions: { level: public })
  @auth(
    rules: [
      { allow: public, operations: [read] }
      { allow: private, operations: [read] }
      { allow: private, provider: iam }
    ]
  ) {
  id: ID!
  name: String!
}

type Call
  @model
  @auth(rules: [{ allow: owner }, { allow: private, provider: iam }]) {
  id: ID!
  owner: String
  duration: Int
}

After running amplify codegen models I manually remove the different auth rules in src/models/schema.js and I only keep the owner rule (see https://github.com/MrHertal/datastore-test/blob/master/src/models/schema.js).

Company works, I can list and get them. Call does not work.

DataStore executes sync queries but it fails:

{
  "data": { "syncCalls": null },
  "errors": [
    {
      "path": ["syncCalls"],
      "data": null,
      "errorType": "Unauthorized",
      "errorInfo": null,
      "locations": [{ "line": 2, "column": 3, "sourceName": null }],
      "message": "Not Authorized to access syncCalls on type Query"
    }
  ]
}

I realized that maybe the DataStore is using the wrong auth mode. So in aws-exports.js, I changed:

"aws_appsync_authenticationType": "API_KEY",

to

"aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",

Now it works better and all the calls are synced !

But I get a new warning regarding companies:

ConsoleLogger.js:97 [WARN] 13:44.938 DataStore - Connection failed: {"errors":[{"errorType":"Unauthorized","message":"Not Authorized to access onCreateCompany on type Subscription"}]}

ConsoleLogger.js:97 [WARN] 13:44.993 DataStore - Connection failed: {"errors":[{"errorType":"Unauthorized","message":"Not Authorized to access onUpdateCompany on type Subscription"}]}

ConsoleLogger.js:97 [WARN] 13:44.995 DataStore - Connection failed: {"errors":[{"errorType":"Unauthorized","message":"Not Authorized to access onDeleteCompany on type Subscription"}]}

So I can list all companies on page load, but I cannot have live updates of companies.

What I learnt is that DataStore is using project default auth mode to sync. So when using different auth modes inside a project, it will not sync well. We should be able to pass an option to DataStore in order to choose the auth mode depending on the model (here Company or Call). The same way we can choose the auth mode when executing a query with the Amplify client (https://docs.amplify.aws/lib/graphqlapi/authz/q/platform/js).