Cognito Analytics are not being sent to Pinpoint when using Authenticator
Before creating a new issue, please confirm:
- [X] I have searched for duplicate or closed issues and discussions.
- [X] I have tried disabling all browser extensions or using a different browser
- [X] I have tried deleting the node_modules folder and reinstalling my dependencies
- [X] I have read the guide for submitting bug reports.
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:
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:
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.
@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?
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?
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:
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?
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!
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.
@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?
https://github.com/aws-amplify/amplify-js/issues/9131
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 isWeb 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).
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
@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.
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.
@nadetastic thanks, looking forward!
Closing due to inactivity