AWS Amplify AppSync订阅无法正常工作

时间:2019-11-08 16:24:16

标签: ionic-framework aws-amplify aws-appsync

我编写了一个小型应用程序,该应用程序使用AWS Amplify CLI / AppSync订阅数据库更改。所有放大的api调用都可以正常工作(变异,查询),但不幸的是观察者没有收到事件。我可以看到MQTT套接字会定期接收二进制文件,但无法获取更改的对象。

我将Amplify配置为放大使用。我在调试器中看到AppSyncProvider已被感染。还尝试了API和PubSub,但没有区别。

        const awsmobile = {
            "aws_appsync_graphqlEndpoint": "https://[...].appsync-api.[...]/graphql",
            "aws_appsync_region": "[...]",
            "aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
        };

        Amplify.configure(awsmobile);

        ngOnInit() 
            {
                try {

                  this.apiService.OnUpdateA.subscribe(
                    {
                        next: (x) => {[...]},
                        error: (e) => {[...]},
                        complete: () => {[...]}
                    });
                } 
                catch (error) {[...]    }
            }

        ***Schema***
        type A
        @model 
        @auth(rules: [
              {allow: owner},
              {allow: groups, groups: ["A"], operations: [create, update, read]},
              {allow: groups, groups: ["B"], operations: [read]},
          ]) 
        {
          id: ID!
          entry: AnotherType! @connection(name: "AnotherConnection")
    [...]
        }

 OnUpdateAListener: Observable<
    OnUpdateASubscription
  > = API.graphql(
    graphqlOperation(
      `subscription OnUpdateA($owner: String) {
        onUpdateA(owner: $owner) {
          __typename
          id
          owner
       [...]
        }
      }`
    )
  ) as Observable<OnUpdateASubscription>;

有人有什么想法吗?

**Logs:**
{mqttConnections: Array(1), newSubscriptions: {…}, provider: Symbol(INTERNAL_AWS_APPSYNC_PUBSUB_PROVIDER)}
mqttConnections: Array(1)
0: {url: "wss://[...]-ats.iot.[...].amazonaws…[...]%3D%3D", topics: Array(2), client: "[...]"}
length: 1
__proto__: Array(0)
newSubscriptions:
onUpdate:
expireTime: 1573313050000
topic: "[....]/22tmaezjv5555h4o7yreu24f7u/onUpdate/1cd033bad555ba55555a20690d3e04e901145776d3b8d8ac95a0aea447b273c3"
__proto__: Object
__proto__: Object
provider: Symbol(INTERNAL_AWS_APPSYNC_PUBSUB_PROVIDER)
__proto__: Object

但是,不确定订阅对象没有队列是否可疑?

Subscription {_observer: {…}, _queue: undefined, _state: "ready", _cleanup: ƒ}
_cleanup: ƒ ()
_observer:
next: (x) => {…}
__proto__: Object
_queue: ***undefined***
_state: "ready"
closed: (...)
__proto__: Object

非常感谢。

4 个答案:

答案 0 :(得分:2)

对于那些经历相同行为的人。这是由于我在架构的auth部分拥有所有者。删除了{allow: owner}部分,订阅立即开始工作。

答案 1 :(得分:0)

这是AWS Amplify订阅的有效示例:


import Amplify from 'aws-amplify';
import API from '@aws-amplify/api';
import PubSub from '@aws-amplify/pubsub';
import awsconfig from './aws-exports';

Amplify.configure(awsconfig);
API.configure(awsconfig);
PubSub.configure(awsconfig);

// put above in root

// below is example 

import { API, graphqlOperation } from 'aws-amplify';

var  onAddNote = `subscription OnCreateNote {
    onCreateNote {
        id
        patient {
            id
            organization {
                id
            }
        }   
    }
}
`;

listenForNoteAdd() {
        return API.graphql(graphqlOperation(onAddNote) ).subscribe({next: (noteData) => {
            console.log("new note so reload consider reload")
            let note = noteData.value.data.onCreateNote
            console.log(JSON.stringify(note))

            // now that you have indication of something happening 
            // do what you must next

        }})    
    }

答案 2 :(得分:0)

我认为您的示例正在使用TypeScript替代方法。我尝试使用生成API.service.ts的ampolify cli的Angular替代方法。

我的订阅是如此之类

OnUpdateAListener: Observable<
    OnUpdateASubscription
  > = API.graphql(
    graphqlOperation(
      `subscription OnUpdateA($owner: String) {
        onUpdateA(owner: $owner) {
          __typename
          id
          oid
          name
          address
         [...]
          owner
        }
      }`
    )
  ) as Observable<OnUpdateASubscription>;

您是否知道是否需要填写订阅中的所有字段以触发事件,或者仅更新某些字段就足够了?

我的假设正确吗,所有者值是自动设置的?

答案 3 :(得分:0)

对于那些遇到此错误的人,请勿删除 {allow: owner}。允许所有者确保只有通过 Cognito 用户池认证的用户才能运行查询、变更等。

看起来 OP 正在使用 amplify codegen 来生成他的 API 服务,并且如果您查看侦听器具有所有者的参数。它是可选的,但如果您的 @auth 是 {allow: owner},则它是必需的。

附加说明:不确定他是否使用了存储在其数据存储中的正确所有者字段。如果尚未创建所有者字段(或指定的不同字段),它将创建一个具有唯一 uuid 的字段。所以他可能会通过错误的所有者或根本没有。

运行一个简单的调用以获取所有者...

export const GetOwner = async (id: string): Promise<GetOwnerQuery> => {
  const statement = `query GetAppData($id: ID!) {
      getAppData(id: $id) {
        owner
      }
    }`;
  const gqlAPIServiceArguments: any = {
    id,
  };
  const response = (await API.graphql(graphqlOperation(statement, gqlAPIServiceArguments))) as any;
  return <GetOwnerQuery>response.data.getAppData;
};

...并在您的订阅中传递它。

const { owner } = await GetOwner(id);
if (owner) {
  this.apiUpdateListener$ = this.api.OnUpdateAppDataListener(owner).subscribe((data) => {
    console.log('api update listener ===> ', data);
  });
}