Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cognito Analytics are not being sent to Pinpoint when using Authenticator #12877

Closed
4 tasks done
ivan-kiselev opened this issue Jan 21, 2024 · 11 comments
Closed
4 tasks done
Labels

Comments

@ivan-kiselev
Copy link

ivan-kiselev commented Jan 21, 2024

Before creating a new issue, please confirm:

On which framework/platform are you having an issue?

React

Which UI component?

Authenticator

How is your app built?

Create React App

What browsers are you seeing the problem on?

Firefox, Safari

Which region are you seeing the problem in?

eu-central-1, us-east-1

Please describe your bug.

User SignUp analytics don't show up in the PinpointAnalytics when using AWS Amplify Authenticator with configured Analytics block:

Amplify.configure({
  Analytics: {
    Pinpoint: {
      bufferSize: 100,
      flushInterval: 30,
      flushSize: 100,
      resendLimit: 10,
      appId: "MY_ID",
      region: "eu-central-1",
    },
  },
  Auth: {
    Cognito: {
      userPoolClientId: "MY_ID",
      userPoolId: "MY_ID",
      signUpVerificationMethod: "link",
      loginWith: {
        username: true,
        email: true,
        phone: false,
      },
    },
  },
});

User sign up is performed successfully, the integration between the AWS Cognito and pinpoint analytics is configured in the console:

Screenshot 2024-01-21 at 16 28 38

What's the expected behaviour?

When I sign up in my App, I want to see some activity in integrated with my Cognito client pinpoint project, but nothing happens.

Documentation states that SignUp event from cognito shall be reflected, though it also mentions vaguely that request should "include an AnalyticsEndpointId value in the AnalyticsMetadata parameter of your API request", which I don't see happening if I inspect requests to Cognito from my UI when I press "sign up" button on Authenticator component. I only see essential for registration data:
Screenshot 2024-01-21 at 16 35 37

Help us reproduce the bug!

Set up cognito user pool, cognito client and integrate the client with pinpoint analytics.

Use this client for web-interface based on the following snippet

Code Snippet

// Put your code below this line.
Amplify.configure({
  Analytics: {
    Pinpoint: {
      bufferSize: 100,
      flushInterval: 30,
      flushSize: 100,
      resendLimit: 10,
      appId: "...",
      region: "eu-central-1",
    },
  },
  Auth: {
    Cognito: {
      userPoolClientId: "...",
      userPoolId: "...",
      signUpVerificationMethod: "link",
      loginWith: {
        username: true,
        email: true,
        phone: false,
      },
    },
  },
});

And Cogntio user pool with a secretless client integrated with Pinpoint app in the same region, and authenticator:

        <Authenticator signUpAttributes={["email"]}>
          {({ signOut, user }) => (
            <View>
              <Heading color="pieCrust.700">Hello {user?.username}</Heading>
              <Text textAlign="center">Welcome to our application!</Text>
              <Button onClick={signOut}>Sign out</Button>
            </View>
          )}
        </Authenticator>

Console log output

No response

Additional information and screenshots

I generally see AnalyticsMetadata in the corresponding library, but I am not sure if I need to do something additionally myself to make the client propagate this field.

I am not really good with frontend, trying me best here, sorry if I am missing something absolutely obvious.

@github-actions github-actions bot added the pending-triage Issue is pending triage label Jan 21, 2024
@thaddmt thaddmt added bug Something isn't working Authenticator and removed pending-triage Issue is pending triage labels Jan 22, 2024
@reesscot reesscot added question General question and removed bug Something isn't working labels Jan 22, 2024
@calebpollman
Copy link
Member

@ivan-kiselev Going to transfer this issue over to our sibling team Amplify JS to see if they can unblock you with the Pinpoint/Cognito integration piece as analytic recording is not handled by the Authenticator without customization

@cwomack Based on the provided info above (see cognito docs) is this something we can help with?

@calebpollman calebpollman transferred this issue from aws-amplify/amplify-ui Jan 23, 2024
@nadetastic nadetastic self-assigned this Jan 23, 2024
@ivan-kiselev
Copy link
Author

So, the only way to get analytics propagated to the pinpoint I've found, is to use low-level AWS APIs, like so:

import { Amplify, ResourcesConfig } from "aws-amplify";
import {
  AuthFlowType,
  CognitoIdentityProviderClient,
  InitiateAuthCommand,
} from "@aws-sdk/client-cognito-identity-provider";

const rawPasswordSignIn = async (
  username: string,
  password: string,
  config: ResourcesConfig
) => {
  const client = new CognitoIdentityProviderClient({
    region: config.Analytics?.Pinpoint?.region,
  });
  const input = {
    ClientId: config.Auth?.Cognito?.userPoolClientId,
    AuthFlow: AuthFlowType.USER_PASSWORD_AUTH,
    AuthParameters: {
      USERNAME: username,
      PASSWORD: password,
    },

    AnalyticsMetadata: {
      AnalyticsEndpointId: config.Analytics?.Pinpoint?.appId,
    },
  };
  const command = new InitiateAuthCommand(input);
  return await client.send(command);
};

And I see all the JWT tokens successfully returned, the Auth, Refresh and ID tokens. Now.. I either have to implement my own auth provider, or feed these tokens in a tricky way somehow to the auth provider of Amplify. I presume, the latter is not recommended, right?

I guess I could write cookies with the same names as Amplify would expect? But something would've gone wrong for sure anyways. So I guess my best shot is to wait until analytics are implemented natively in Amplify library and until then implementing authentication logic myself?

@ivan-kiselev
Copy link
Author

Ok, so I thought I am going to be smart and do the following:

import { record } from "@aws-amplify/analytics";
import { signIn } from "@aws-amplify/auth";

  const handleSignIn = async () => {
      const response = await signIn({ username, password });
      record({
        name: "_userauth.sign_in",
        attributes: {
          CognitoClientId: `(web) ${config.Auth?.Cognito?.userPoolClientId}`,
        },
      });
      flushEvents();
      console.log(response);
  };

E.g. use amplify function for sign-in operation so it propagates all the cookies and what not to the wrapping Authenticator.Provider provider and then record the event in analytics manually, imitating the way it'd be done by Cognito, but it's troublesome and totally not the same.

record call finishes in the warning:

Screenshot 2024-01-24 at 10 11 13

And indeed if one exercises fetchAuthSession from @aws-amplify/auth, it will yield empty credentials even after successful signIn with all the cookies present, so I guess it's just not the same to first signin/signup and then send an analytics event separately, especially considering that AnalyticsMetadata is straight up a field for the SignUp Cognito request and this analytics events are supposedly coming from Cognito and not client.

So yeah. The only way to do that properly is to have it handled in amplify libs themselves.

@cwomack any chances it could be an easy fix?

@ivan-kiselev
Copy link
Author

Hey @reesscot @nadetastic @cwomack The PR is ready for initial review, I haven't updated docs presuming there are going to be corrections to the PR, I will do so shall changes be approved.

Would appreciate if you could give it a look!

@nadetastic
Copy link
Member

Hi @ivan-kiselev thank you for your contribution!

I've been taking a look at this issue to better understand and validate the problem, but I believe that as long as your user pool client is connected to Pinpoint it should automatically send the events without additional config since under the hood the library will invoke the supported API actions such as InitiateAuth for signIn.

I will follow up soon with an update and also further discuss with the team. Let me know if you have any additional question in the meantime.

@nadetastic
Copy link
Member

nadetastic commented Jan 25, 2024

@ivan-kiselev follow up question. It looks like you manually created the Cognito and Pinpoint resource without the Amplify CLI - in that case, what may be missing are the permissions needed by Cognito Identity pool roles to be able to send events to Pinpoint.

Have you had a chance to review this related issue/comment?

#9131

@ivan-kiselev
Copy link
Author

ivan-kiselev commented Jan 26, 2024

I believe that as long as your user pool client is connected to Pinpoint it should automatically send the events without additional config since under the hood the library will invoke the supported API actions such as InitiateAuth for signIn.

That's not entirely true. From the very same documentation page that you mentioned:

To pass metadata about your user's session to your Amazon Pinpoint campaign, include an AnalyticsEndpointId value in the AnalyticsMetadata parameter of your API request

In other words, Cognito <=> Pinpoint analytics works in such a way that if your requests to Cognito don't include appropriate AnalyticsMetadata, your analytics events won't make it to Pinpoint, and I can confirm it from my experience. That's why I opened this issue to begin with.

The linked PR introduces this to the code, enriching requests with analytics metadata shall it be present on the top level config.

what may be missing are the permissions needed by Cognito Identity pool roles to be able to send events to Pinpoint.

I believe the author of the linked issue had the same problem, but the person replying got confused (fairly so) a bit and addressed different, though seemingly similar problem.

From the perspective of current github issue and the one you linked, there are two distinct sources of events for Pinpoint analytics:

  • Events that are coming to Pinpoint from web applications (e.g. when user directly calls record({...}) from @aws-amplify/analytics. E.g. Chain of interaction is Web Client => AWS Pinpoint.
  • Events that are coming to Pinpoint from Cognito when user authorizes. E.g. Chain of interaction is Web Client => AWS Cognito => AWS Pinpoint.

So, what you are referring to, is the first case, when Web Client directly sends events to the Pinpoint, and the comment you linked is legit for that case.

What current Issue and corresponding PR are about, is the second case, when User interacts with Cognito, and Cognito, in turn, sends analytical events to Pinpoint.

Now, about permissions. I do believe one doesn't need to create/associate their own IAM permissions for the case I am talking about. As a proof, try to associate Pinpoint project with a Cognito Client through UI, you will see the following (read the Permission to access Amazon Pinpoint section).

Screenshot 2024-01-26 at 12 37 04

Same with terraform, if you try to just run this, without creating any special permissions or roles, AWS will work it's magic and create trust relationships between cognito-idp service and standard role that has required permissions:

resource "aws_cognito_user_pool_client" "web" {
  name                          = "web"
...
  // Must be configured through ARN, otherwise it gets misconfigured, see
  // https://github.com/hashicorp/terraform-provider-aws/issues/35418
  analytics_configuration {
    application_arn  = aws_pinpoint_app.authentication_activity.arn
    user_data_shared = true
  }
}

resource "aws_pinpoint_app" "authentication_activity" {
  name = "authentication_activity"
}

With the configuration above, Cognito-related events start popping up in pinpoint without any additional configuration (but be patient if you are going to test it, it might take up to 15 minutes between sign up is triggered/confirmed and it appears in Pinpoint, it's very async)

Does this address your concern?

@nadetastic

@ivan-kiselev
Copy link
Author

@nadetastic Friendly ping here

I'd need to decide whether to stick to Amplify for the long term in the project or implement everything myself, and analytics integration between cognito and pinpoint not being implemented on Amplify side is one of the decision factors.

@nadetastic
Copy link
Member

Hi @ivan-kiselev thank you for you patience, and for clearing this issue up for me, as well as your contribution for addressing this use case! I've discussed this with the team and we are currently reviewing the PR you submitted - will follow up on it soon with any additional feedback. But in the meantime let me know if you have any additional comment/questions - I'll also make sure to provide an update again soon.

@ivan-kiselev
Copy link
Author

@nadetastic thanks, looking forward!

@nadetastic nadetastic added the feature-request Request a new feature label Feb 13, 2024
@cwomack cwomack removed the question General question label May 9, 2024
@ivan-kiselev
Copy link
Author

Closing due to inactivity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants