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.41k stars 2.12k forks source link

Pub/Sub entering ConnectionDisrupted state, no errors #11304

Open Nikola-Milovic opened 1 year ago

Nikola-Milovic commented 1 year ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

PubSub

Amplify Categories

auth

Environment information

``` System: OS: Linux 5.15 Ubuntu 20.04.5 LTS (Focal Fossa) CPU: (16) x64 AMD Ryzen 7 2700 Eight-Core Processor Memory: 17.90 GB / 31.30 GB Container: Yes Shell: 5.0.17 - /usr/bin/bash Binaries: Node: 18.14.2 - ~/.nvm/versions/node/v18.14.2/bin/node Yarn: 1.22.19 - /usr/bin/yarn npm: 9.5.0 - ~/.nvm/versions/node/v18.14.2/bin/npm Watchman: 2023.03.20.00 - /home/linuxbrew/.linuxbrew/bin/watchman Browsers: Brave Browser: 107.1.45.118 Chrome: 107.0.5304.87 Chromium: 112.0.5615.49 Firefox: 112.0.1 npmGlobalPackages: corepack: 0.15.3 npm: 9.5.0 pnpm: 8.1.1 ```

Describe the bug

When trying to connect to AWS IoT with Amplify and Pub/Sub I am stuck in the ConnectionDisturbed -> Connection loop

[INFO] 43:52.175 Main - Connecting
ConsoleLogger.ts:105 [INFO] 43:52.339 Main - ConnectionDisrupted
ConsoleLogger.ts:105 [INFO] 44:52.174 Main - Connecting
ConsoleLogger.ts:105 [INFO] 44:52.350 Main - ConnectionDisrupted
ConsoleLogger.ts:105 [INFO] 45:52.174 Main - Connecting
ConsoleLogger.ts:105 [INFO] 45:52.345 Main - ConnectionDisrupted

Expected behavior

It should be in connected state and stay in it

Reproduction steps

Have my CDK configuration with my amplify.ts file

Code Snippet

My setup is as follows

amplify.ts file that I import in the entrypoint to my app

Logger.LOG_LEVEL = 'DEBUG' ;

try {
    const cancel = Hub.listen('pubsub', (data: any) => {
         console.log('PubSub', data) 
    });

    Amplify.configure({
        Auth: {
            region: env.AWS_REGION,
            userPoolId: env.AWS_COGNITO_USER_POOL_ID,
            userPoolWebClientId: env.AWS_COGNITO_ADMIN_USER_POOL_CLIENT_ID,
            identityPoolId: env.AWS_COGNITO_IDENTITY_POOL_ID,
            identityPoolRegion: env.AWS_REGION,
            mandatorySignIn: true
        },
        }

    Amplify.addPluggable(
        new AWSIoTProvider({
            aws_pubsub_region: env.AWS_REGION,
            aws_pubsub_endpoint: `wss://${env.AWS_IOT_ENDPOINT}/mqtt`,
        })
    );
} catch (error) {
    console.error("error occured during amplify setup", error);
}

All of my env variables are correct, I also have geo setup, and its working.

The endpoint also matches the one in IoT Core -> Settings.

This is my endpoint wss://a3ri7xxxxxxxxx-ats.iot.eu-central-1.amazonaws.com/mqtt

I receive no errors other than the connection being disrupted. If I try to publish I get [undefined] back without any errors.


I am not using the CLI but my own CDK and I have this

        const iotPolicy = new iam.Policy(this, `iot-amplify-policy`, {
            statements: [
                new iam.PolicyStatement({
                    effect: iam.Effect.ALLOW,
                    actions: ['iot:*'],
                    resources: [`arn:aws:iot:${appConfig.region}:${appConfig.account}:*`],
                }),
            ],
        });

        const { authenticatedRole } = props;

        authenticatedRole.attachInlinePolicy(iotPolicy);

        authenticatedRole.addManagedPolicy(
            iam.ManagedPolicy.fromAwsManagedPolicyName('AWSIoTDataAccess')
        );
        authenticatedRole.addManagedPolicy(
            iam.ManagedPolicy.fromAwsManagedPolicyName('AWSIoTConfigAccess')
        );

So my Authenticated users should have access to the IoT.

Log output

``` // Put your logs below this line ```

Additional information

There was an issue that mentions something related to access to Pub/Sub IoT but it was closed and not answered https://github.com/aws-amplify/amplify-js/issues/749, doesn't seem to be the issue I am experiencing

Also if I try to connect over plain MQTT instead of websockets or with HTTPS, then I am stuck in Connecting state.

Not sure how to debug without any error logs, not sure what could cause such behaviour.

My only guess is that I am misunderstanding roles and users and that the Policy I gave to my authenticated users is in fact not doing what I expect it to. As in the docs its stated

The next step is attaching the policy to your Cognito Identity.

While I am not attaching it to Cognito Identity.

Nikola-Milovic commented 1 year ago

Identity had to have the policy and not the authenticated user. This fixed the issue

Edit: I'll leave this open as a question on how to grant access to authenticated users without having to have a separate endpoint to handle adding the policy for identity. Maintainers please close this, I'll leave it open for visibility. As https://github.com/aws-amplify/amplify-js/issues/749 left unanswered and I couldn't find the answer anywhere. If there is no way around it, any tips on how to implement it? As identities are temporary, how should I approach expiration and such

Julz-afk commented 1 year ago

Hi @Nikola-Milovic, did you get this issue resolved on your side? I am experiencing similar issue.

Nikola-Milovic commented 1 year ago

The comment I made is the fix, basically you need the policy on the identity itself. But I have no way of easily automating this, nor do I have an idea on why my setup with Authenticated role wasn't working.

Julz-afk commented 1 year ago

@Nikola-Milovic, Are you referring to the identity ID of the user or the Identity pool ID?

Nikola-Milovic commented 1 year ago

@Julz-afk Identity of the authenticated user, I think attaching it to Identity Pool doesn't work. You can try and please let me know

Julz-afk commented 1 year ago

Yeah I have tried using the Auth user ID and also the pool ID, both not working on my side, still getting this error: connecting then connection disrupted. Then this error pops up: MqttOverWSProvider - Error forming connection Error: AMQJS0011E

Nikola-Milovic commented 1 year ago

@Julz-afk follow the guide in their docs, if you attach the policy manually it works

Julz-afk commented 1 year ago

Got it up and running on my side, think I missed a step somewhere with the policy and identity stuff.

mikey0000 commented 1 year ago

Also in nodejs applications WebSockets is missing as in never imported and is expected on the global.

mufarrah commented 12 months ago

@Julz-afk Identity of the authenticated user, I think attaching it to Identity Pool doesn't work. You can try and please let me know

Thanks , that helped, you are right

LorisNanchen commented 8 months ago

Where can I find that Identity Id ? I'm facing the same issue and nothing seems to fix it. Maybe I didn't understand the Policies and Identities.

Btw I'm using NextJs, don't know if it's supposed to work with it.

waedg commented 6 months ago

I confirm, in my case i didn't created and added the policy to the user after authentification , i recommand reading this section of amplify documentation and understand it very well : [https://docs.amplify.aws/javascript/build-a-backend/more-features/pubsub/set-up-pubsub/] thank you @Nikola-Milovic for the hint.

haverchuck commented 1 month ago

Is this issue happening on version 5 only?