Hi, I have a question about Analytics.updateEndpoint(), my case is:
import Amplify, {
Analytics
} from 'aws-amplify';
Amplify.configure({
Auth: {
region: process.env.REACT_APP_AWS_REGION,
identityPoolId: process.env.REACT_APP_AWS_IDENTITY_POOL_ID,
userPoolId: process.env.REACT_APP_AWS_USER_POOL_ID,
userPoolWebClientId: process.env.REACT_APP_AWS_USER_POOL_CLIENT_ID,
},
Analytics: {
AWSPinpoint: {
region: process.env.REACT_APP_AWS_REGION,
appId: process.env.REACT_APP_AWS_PINPOINT_APP_ID,
mandatorySignIn: false
}
}
});
Auth.currentUserInfo().then((info) => {
Analytics.updateEndpoint({
userId: info.attributes.sub,
userAttributes: info.attributes
}).then((data) => {
dispatch(setProgress(false));
dispatch({
type: LOGIN_SUCCESS,
user: data
});
dispatch(redirectTo('/'));
});
}).catch(error => {
dispatch(setProgress(false));
dispatch({
type: LOGIN_ERROR,
error: error
});
});
But when I invoke the method, on the Network tab on Google Chrome, the request is not there. I set up the Pinpoint to Stream events to Firehose and when I saw on S3 Files de userAttributes is empty and the UserId is not changing.
I would like to known if can I change endpoint Information after configure Amplify on startup?
Thanks
@lucasvieirasilva, from what I see, you did everything right except that your endpoint needs an address. If your default config does not contain an endpoint address, you need to pass in one the first time you call updateEndpoint. You may try something like this:
Auth.currentUserInfo()
.then(info =>
Analytics.updateEndpoint({
address: info.attributes.email, // Or phone_number
channelType: 'EMAIL', // Or 'SMS'
userId: info.attributes.sub,
userAttributes: info.attributes
})
)
.then(() => console.log('Do something else'));
Hi @temideoye, I added address and channelType fields in updateEndpoint request, but updating endpoint still not working.
Thanks
@lucasvieirasilva, can you share some log info? Enable debug log with Amplify.Logger.LOG_LEVEL = 'DEBUG'
and try again.
Hi @temideoye, after turning on the debug log, I saw the problem in the browser console, apparently the field UserAttributes must be an Array.
The console log:
[DEBUG] 53:30.612 AWSPinpointProvider - no change for aws credentials, directly return from init
ConsoleLogger.js:107
[DEBUG] 53:30.613 AWSPinpointProvider - updateEndpoint with params: {ApplicationId: "38329aefc2e645189d72b9f51fd736f0", EndpointId: "0afbfae0-128f-11e9-84aa-8f3b8448fbfb", EndpointRequest: {鈥}ApplicationId: "38329aefc2e645189d72b9f51fd736f0"EndpointId: "0afbfae0-128f-11e9-84aa-8f3b8448fbfb"EndpointRequest: {ChannelType: "EMAIL", RequestId: "86777a50-12ad-11e9-914e-73f3bef74cf1", EffectiveDate: "2019-01-07T18:53:30.613Z", Address: "*******@*****.com", Attributes: {鈥,聽鈥Address: "*******@*****.com"Attributes: {}ChannelType: "EMAIL"Demographic: {AppVersion: "Chrome/71.0.3578.98", Make: "Gecko", Model: "Chrome", ModelVersion: "71.0.3578.98", Platform: "MacIntel"}EffectiveDate: "2019-01-07T18:53:30.613Z"Location: {}Metrics: {}RequestId: "86777a50-12ad-11e9-914e-73f3bef74cf1"User: {UserId: "65db3e77-8bc7-45ed-92b4-6b8713ce15e1", UserAttributes: {鈥}__proto__: Object__proto__: Object
ConsoleLogger.js:107
[DEBUG] 53:30.618 AWSPinpointProvider - updateEndpoint failed Error: There were 3 validation errors:
* InvalidParameterType: Expected params.EndpointRequest.User.UserAttributes['sub'] to be an Array
* InvalidParameterType: Expected params.EndpointRequest.User.UserAttributes['email_verified'] to be an Array
* InvalidParameterType: Expected params.EndpointRequest.User.UserAttributes['email'] to be an Array
at ParamValidator.validate (param_validator.js:42)
at Request.VALIDATE_PARAMETERS (event_listeners.js:141)
at Request.callListeners (sequential_executor.js:115)
at callNextListener (sequential_executor.js:102)
at event_listeners.js:94
at finish (config.js:324)
at getStaticCredentials (config.js:353)
at Config.getCredentials (config.js:361)
at Request.VALIDATE_CREDENTIALS (event_listeners.js:86)
at Request.callListeners (sequential_executor.js:110)
at Request.emit (sequential_executor.js:82)
at Request.emit (request.js:697)
at Request.transition (request.js:30)
at AcceptorStateMachine.runTo (state_machine.js:16)
at Request.runTo (request.js:406)
at Request.send (request.js:371)
at features.constructor.makeRequest (service.js:218)
at features.constructor.svc.(anonymous function) [as updateEndpoint] (http://localhost:3000/static/js/0.chunk.js:36744:23)
at AWSPinpointProvider.js:699
at new Promise (<anonymous>)
at AWSPinpointProvider.<anonymous> (AWSPinpointProvider.js:698)
at step (AWSPinpointProvider.js:137)
at Object.next (AWSPinpointProvider.js:67)
at AWSPinpointProvider.js:39
at new Promise (<anonymous>)
at push../node_modules/@aws-amplify/analytics/lib/Providers/AWSPinpointProvider.js.__awaiter (AWSPinpointProvider.js:16)
at AWSPinpointProvider._updateEndpoint (AWSPinpointProvider.js:677)
at AWSPinpointProvider.<anonymous> (AWSPinpointProvider.js:321)
at step (AWSPinpointProvider.js:137)
at Object.next (AWSPinpointProvider.js:67)
at AWSPinpointProvider.js:39
at new Promise (<anonymous>)
at push../node_modules/@aws-amplify/analytics/lib/Providers/AWSPinpointProvider.js.__awaiter (AWSPinpointProvider.js:16)
at AWSPinpointProvider._sendFromBuffer (AWSPinpointProvider.js:264)
at AWSPinpointProvider.js:239
My fix:
Auth.currentUserInfo().then((info) => {
console.log('Begin Update Endpoint...');
const userAttributes = {};
for (const key in info.attributes) {
userAttributes[key] = [info.attributes[key].toString()];
}
Analytics.updateEndpoint({
address: info.attributes.email,
channelType: 'EMAIL',
userId: info.attributes.sub,
userAttributes
}).then((data) => {
console.log('End Update Endpoint...');
dispatch(setProgress(false));
dispatch({
type: LOGIN_SUCCESS,
user: data
});
dispatch(redirectTo('/'));
});
}).catch(error => {
dispatch(setProgress(false));
dispatch({
type: LOGIN_ERROR,
error: error
});
});
console log after code changes:
[DEBUG] 13:11.884 AWSPinpointProvider - updateEndpoint with params: {ApplicationId: "38329aefc2e645189d72b9f51fd736f0", EndpointId: "0afbfae0-128f-11e9-84aa-8f3b8448fbfb", EndpointRequest: {鈥}ApplicationId: "38329aefc2e645189d72b9f51fd736f0"EndpointId: "0afbfae0-128f-11e9-84aa-8f3b8448fbfb"EndpointRequest: Address: "*******@*****.com"Attributes: {}ChannelType: "EMAIL"Demographic: {AppVersion: "Chrome/71.0.3578.98", Make: "Gecko", Model: "Chrome", ModelVersion: "71.0.3578.98", Platform: "MacIntel"}EffectiveDate: "2019-01-07T19:13:11.884Z"Location: {}Metrics: {}RequestId: "468f20c0-12b0-11e9-96ff-011d3d6c2de8"User: UserAttributes: email: ["*******@*****.com"]email_verified: ["true"]sub: ["65db3e77-8bc7-45ed-92b4-6b8713ce15e1"]__proto__: ObjectUserId: "65db3e77-8bc7-45ed-92b4-6b8713ce15e1"__proto__: Object__proto__: Object__proto__: Object
ConsoleLogger.js:97 [DEBUG] 13:11.889 AWSPinpointProvider - init clients
ConsoleLogger.js:97 [DEBUG] 13:11.893 AWSPinpointProvider - no change for aws credentials, directly return from init
ConsoleLogger.js:97 [DEBUG] 13:11.894 AWSPinpointProvider - record event with params
ConsoleLogger.js:107 [DEBUG] 13:11.894 AWSPinpointProvider - pinpoint put events with params {ApplicationId: "38329aefc2e645189d72b9f51fd736f0", EventsRequest: {鈥}
ConsoleLogger.js:107 [DEBUG] 13:12.279 AWSPinpointProvider - updateEndpoint success {MessageBody: {鈥}
It's works
Thank you very much for your help
Oh yeah, that totally eluded me too. Glad the log helped you figure it out.
Yes, another thing is that all attribute values must be string!
@lucasvieirasilva, from what I see, you did everything right except that your endpoint needs an address. If your default config does not contain an endpoint address, you need to pass in one the first time you call updateEndpoint. You may try something like this:
Updating this for future reference
userAttributes object expects array values. Right implementation should be:
Auth.currentUserInfo()
.then(({ attributes }) => {
const userAttributes = {};
Object.entries(attributes).forEach(([key, value]) => {
userAttributes[key] = [`${value}`];
});
Analytics.updateEndpoint({
address: attributes.email, // Or phone_number
channelType: 'EMAIL', // Or 'SMS'
userId: attributes.sub,
userAttributes
});
})
.then(() => console.log('Do something else'));
shouldn't this be in the docs or even be done automatically? I lost countless hours trying to figure out how to get user data into pinpoint.
if you use lodash it can be written like this:
Auth.currentUserInfo().then(({ attributes }) => {
Analytics.updateEndpoint({
address: attributes.email,
userId: attributes.sub,
userAttributes: _.mapValues(attributes, value => [`${value}`]),
});
});
@madmed88 I think so, too. Made a detailed tutorial here.
@lucasvieirasilva, from what I see, you did everything right except that your endpoint needs an address. If your default config does not contain an endpoint address, you need to pass in one the first time you call updateEndpoint. You may try something like this:
Updating this for future reference
userAttributes object expects array values. Right implementation should be:Auth.currentUserInfo() .then(({ attributes }) => { const userAttributes = {}; Object.entries(attributes).forEach(([key, value]) => { userAttributes[key] = [`${value}`]; }); Analytics.updateEndpoint({ address: attributes.email, // Or phone_number channelType: 'EMAIL', // Or 'SMS' userId: attributes.sub, userAttributes }); }) .then(() => console.log('Do something else'));
Is this still the case for getting user attributes into Pinpoint? @kaustavghosh06 @dabit3
Not sure how I unassigned @powerful23 ? Is this a feature of GitHub? :D
Most helpful comment
Updating this for future reference
userAttributes object expects array values. Right implementation should be: