aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.43k stars 2.13k forks source link

Subscription returning null in app, works on AppSync console #8888

Closed carolynwang closed 3 years ago

carolynwang commented 3 years ago

Before opening, please confirm:

JavaScript Framework

React Native

Amplify APIs

GraphQL API

Amplify Categories

api

Environment information

``` # Put output below this line System: OS: macOS High Sierra 10.13.6 CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz Memory: 791.81 MB / 8.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 14.17.3 - /usr/local/bin/node npm: 6.14.13 - /usr/local/bin/npm Browsers: Chrome: 93.0.4577.63 Firefox: 88.0.1 Safari: 13.1.2 npmPackages: @babel/core: ^7.9.0 => 7.9.0 @iconify-icons/ion: ^1.1.2 => 1.1.2 @iconify/react: ^1.1.4 => 1.1.4 @react-native-async-storage/async-storage: ^1.15.7 => 1.15.7 @react-native-community/async-storage: ^1.12.1 => 1.12.1 @react-native-community/eslint-config: 1.1.0 @react-native-community/eslint-plugin: 1.0.0 @react-native-community/masked-view: ^0.1.10 => 0.1.10 @react-native-community/netinfo: ^6.0.1 => 6.0.1 @react-navigation/bottom-tabs: ^5.11.11 => 5.11.11 @react-navigation/native: ^5.9.4 => 5.9.4 HelloWorld: 0.0.1 aws-amplify: ^4.2.4 => 4.2.4 aws-amplify-react-native: ^5.0.3 => 5.0.3 babel-plugin-inline-view-configs: 0.0.5 expo: ~41.0.1 => 41.0.1 expo-status-bar: ~1.0.4 => 1.0.4 hermes-inspector-msggen: 1.0.0 react: 16.13.1 => 16.13.1 react-animated: 0.1.0 react-dom: 16.13.1 => 16.13.1 react-native: https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz => 0.63.2 react-native-codegen: 0.0.2 react-native-gesture-handler: ^1.10.3 => 1.10.3 react-native-reanimated: ^2.1.0 => 2.1.0 react-native-safe-area-context: ^3.2.0 => 3.2.0 react-native-screens: ^3.0.0 => 3.0.0 react-native-web: ~0.13.12 => 0.13.18 npmGlobalPackages: @aws-amplify/cli: 5.3.1 @calblueprint/whales: 0.1.9 expo-cli: 4.7.3 npm: 6.14.13 ```

Describe the bug

The bug we are seeing seems to be same as the one described in https://github.com/aws-amplify/amplify-js/issues/4832, however the solution that was provided did not work for us.

We are building a ReactNative app, using AppSync mutations and subscriptions, and using the Amplify API. We have tested the subscriptions in the AppSync console, and it is successfully returns a correct response when we fire the corresponding mutation. When we call the same subscription in JS, the response we get is null. This is true for both our custom mutation/subscriptions and the ones that were autogenerated for us.

Expected behavior

Return all the requested data.

Reproduction steps

  1. Set up AppSync from scratch a. Schema:
    
    type Mutation {
    addItem(one: String, two: String, three: String): info
    }

type Query { getInfo(one: String!, two: String!): info }

type Subscription { onAddInfo(one: String, two: String, three: String): info @aws_subscribe(mutations: ["addItem"]) }

type info { one: String two: String three: String }

schema { query: Query mutation: Mutation subscription: Subscription }

  b. Create a NoneType data source
  c. Create resolver for mutation to the NoneType data source
Request mapping:

{ "version": "2017-02-28", "payload": $util.toJson($context.args) }

Response mapping:

$util.toJson($context.result)


2. Test in console to see if it displays correctly (subscription)
3. Create React Native project, integrate AppSync API with the app with amplify, run the subscription, and test with a mutation from the console.
4. See console prints

### Code Snippet

```javascript
// Put your code below this line.
  async function fetchItems() {
    try {
      const todoData = await API.graphql(graphqlOperation(onAddInfo)).subscribe({
        next: subOnAddItem => {
          console.log(subOnAddItem.value) // should return null for the onAddItem field

          // should return TypeError: null is not an object
          setItems(items => [
            ...items,
            [
                subOnAddItem.value.data.onAddItem.one
            ]
          ]);
        },
        error: error => console.warn(error)
      });
    } catch (err) { console.log(err) }
  }

Log output

``` // Put your logs below this line Object { "data": Object { "onAddItem": null, }, } TypeError: null is not an object (evaluating 'subOnAddItem.value.data.onAddItem.one') at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException at node_modules/react-native/Libraries/Core/ExceptionsManager.js:171:19 in handleException at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError at node_modules/expo-error-recovery/build/ErrorRecovery.fx.js:12:21 in ErrorUtils.setGlobalHandler$argument_0 at [native code]:null in flushedQueue at [native code]:null in invokeCallbackAndReturnFlushedQueue ```

aws-exports.js

const awsmobile = {
    "aws_project_region": "us-west-2",
    "aws_appsync_graphqlEndpoint": "https://XXX.appsync-api.us-west-2.amazonaws.com/graphql",
    "aws_appsync_region": "us-west-2",
    "aws_appsync_authenticationType": "API_KEY",
    "aws_appsync_apiKey": "XXX"
};

export default awsmobile;

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

daniel22506 commented 3 years ago

Any updates on this error? We are currently running into the same issue

lawrenceswang commented 3 years ago

Also running into this problem; any help would be appreciated!

aws-eddy commented 3 years ago

Hey @carolynwang, thank you for opening this issue.

I am going to take a look at this issue to see if I can uncover what seems to be the root cause

aepmont commented 3 years ago

I have the same issue in Angular AppSync Subscriptions just dont work Returning errors as 'message: "AppSync Realtime subscription init error: undefined" Documetation does not help at all, being at this issue for the last 10 days

zachjonesnoel commented 3 years ago

+1 Encountered the same issue on a Vue app which is subscribing to multiple subscriptions.

carolynwang commented 3 years ago

Hi @evcodes, are there any updates on this issue?

aws-eddy commented 3 years ago

Yes, I was not able to reproduce your issue after following the getting started guide. However, I do believe there may be some issues with how you setup your mutations/subscriptions. I have not looked into this much yet.

chrisbonifacio commented 3 years ago

@carolynwang looks like you're subscribing to a onAddEmail mutation when your schema defined it as onAddInfo?

carolynwang commented 3 years ago

@chrisbonifacio Sorry, I edited our actual code and schema to make it simpler for this github issue and forgot to change it to onAddInfo. I've edited the description to say onAddInfo now. For clarification, the API was not created with the Amplify CLI but was created directly in the AppSync console (Create API -> Create with wizard), which generated a default schema. I did some experiments and all the default mutation/subscriptions (create, modify, and delete) also return null in the react native app but works perfectly in the AppSync console.

chrisbonifacio commented 3 years ago

I set the same schema that was shared with a None type data source. Ran a mutation through AppSync console, which seemed to work.

Screen Shot 2021-10-25 at 3 32 34 PM

subscribed to mutation on AppSync console, which also seemed to work

Screen Shot 2021-10-25 at 4 04 49 PM

However, subscribing to the mutation in a React Native app did not reproduce the issue. The subscription resulted in:

Screen Shot 2021-10-25 at 4 02 40 PM
chrisbonifacio commented 3 years ago

My graphql/subscriptions.js file

export const onAddInfo = /* GraphQL */ `
  subscription OnAddInfo($one: String, $two: String, $three: String) {
    onAddInfo(one: $one, two: $two, three: $three) {
      one
      two
      three
    }
  }
`;

React Native code:

  useEffect(() => {
    const sub = API.graphql(graphqlOperation(onAddInfo)).subscribe({
      next: subOnAddInfo => {
        console.log(subOnAddInfo.value); // should return null for the onAddItem field

        // should return TypeError: null is not an object
        setItems(items => [...items, subOnAddInfo.value.data.onAddInfo]);
      },
      error: error => console.warn(error),
    });

    return () => sub.unsubscribe();
  }, []);
david-mcafee commented 3 years ago

@carolynwang please see @chrisbonifacio's comment above. Does this match your implementation? Thanks!!

carolynwang commented 3 years ago

@david-mcafee @chrisbonifacio @evcodes Just tried it again (without changing anything) and it is suddenly working now. Thanks for your help on this!

aepmont commented 3 years ago

Hi Guys, i have fixed it in my end (Angular) hope this helps: 1) Amplify needs to use Auth method from aws-amplify not @aws-amplify 2) Amplify.configure(exports) is all you need (also import from aws-amplify) 3) You can use amazon-cognito-identity-js library to create a custom user and attributes 4) Use default API.Service which is autogenerated cause it has a bit of complexity 5) Subscription must use this format: this.subscriptionv = ( this.api.OnCreateBidsAllListener(this.predio_id).subscribe((event:any)=> { console.log('NEW DATA', event.value.data); }) )

Hence you need Subscription from rxjs not appsync Subscription (a bit weird) 6) For reads you can simply call API.graphql, but for writes you can use default api and will do all the handling for you (if this does not work it means something is misconfigured and appsync/amplify wont tell you) 7) Configuration of amazon cognito user pools must have ALLOW_ADMIN_USER_PASSWORD_AUTH 8) Use client idp as well (starting with 4-XXXX rather than the 5/6-xxxx) 9) Make sure your cognito credentials load faster than the creation of the network socket, -> ngAfterViewInit can help with this. 10) Validate all custom lambdas (AWS Cloud) to return all declared values 11) Now socket should run smoothly, if not create a testing CRUD with default libraries, often package.json contains imports which are not needed or clash between them,making a painful import of methods in components

aepmont commented 3 years ago

You can use appsync console to generate the schema, thus importing schema with amplify codegen command (see console)

chrisbonifacio commented 3 years ago

@carolynwang Awesome! Glad it's working 😄 There have been some issues in the past where the fields being returned in the mutation need to match the fields in the subscription. If they don't match, the subscription will receive null for the fields that were not returned by the mutation.

NiksanJP commented 2 years ago

@david-mcafee @chrisbonifacio @evcodes Just tried it again (without changing anything) and it is suddenly working now. Thanks for your help on this!

I am having the this problem for mutations, I did not touch graphql at all but suddenly this API started to convert the args to null.

github-actions[bot] commented 1 year ago

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server amplify-help forum.