amplify-js
amplify-js copied to clipboard
identifyUser in react and react native on in-app and push notification fail to populate many fields (location, timezone,locale)
Before opening, please confirm:
- [X] I have searched for duplicate or closed issues and discussions.
- [X] I have read the guide for submitting bug reports.
- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
JavaScript Framework
React, React Native
Amplify APIs
Push Notifications
Amplify Version
v6
Amplify Categories
notifications
Backend
Amplify CLI
Environment information
# Put output below this line
System:
OS: macOS 13.6.3
CPU: (8) arm64 Apple M2
Memory: 32.64 MB / 8.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.10.0 - /usr/local/bin/node
Yarn: 1.22.21 - /usr/local/bin/yarn
npm: 10.2.3 - /usr/local/bin/npm
Watchman: 2023.12.04.00 - /opt/homebrew/bin/watchman
Browsers:
Chrome: 121.0.6167.160
Safari: 17.2.1
npmPackages:
@aws-amplify/auth: ^6.0.10 => 6.0.15
@aws-amplify/auth/cognito: undefined ()
@aws-amplify/auth/cognito/server: undefined ()
@aws-amplify/auth/enable-oauth-listener: undefined ()
@aws-amplify/auth/server: undefined ()
@aws-amplify/core: ^6.0.10 => 6.0.15
@aws-amplify/core/internals/adapter-core: undefined ()
@aws-amplify/core/internals/aws-client-utils: undefined ()
@aws-amplify/core/internals/aws-client-utils/composers: undefined ()
@aws-amplify/core/internals/aws-clients/cognitoIdentity: undefined ()
@aws-amplify/core/internals/aws-clients/pinpoint: undefined ()
@aws-amplify/core/internals/providers/pinpoint: undefined ()
@aws-amplify/core/internals/utils: undefined ()
@aws-amplify/core/server: undefined ()
@aws-amplify/ui-react: ^6.0.7 => 6.1.1
@aws-amplify/ui-react-internal: undefined ()
@aws-amplify/ui-react-notifications: ^2.0.9 => 2.0.9
@emotion/react: ^11.11.3 => 11.11.3
@emotion/styled: ^11.11.0 => 11.11.0
@mui/icons-material: ^5.15.9 => 5.15.9
@mui/material: ^5.15.9 => 5.15.9
@testing-library/jest-dom: ^5.17.0 => 5.17.0
@testing-library/react: ^13.4.0 => 13.4.0
@testing-library/user-event: ^13.5.0 => 13.5.0
aws-amplify: ^6.0.15 => 6.0.15
aws-amplify/adapter-core: undefined ()
aws-amplify/analytics: undefined ()
aws-amplify/analytics/kinesis: undefined ()
aws-amplify/analytics/kinesis-firehose: undefined ()
aws-amplify/analytics/personalize: undefined ()
aws-amplify/analytics/pinpoint: undefined ()
aws-amplify/api: undefined ()
aws-amplify/api/server: undefined ()
aws-amplify/auth: undefined ()
aws-amplify/auth/cognito: undefined ()
aws-amplify/auth/cognito/server: undefined ()
aws-amplify/auth/enable-oauth-listener: undefined ()
aws-amplify/auth/server: undefined ()
aws-amplify/datastore: undefined ()
aws-amplify/in-app-messaging: undefined ()
aws-amplify/in-app-messaging/pinpoint: undefined ()
aws-amplify/push-notifications: undefined ()
aws-amplify/push-notifications/pinpoint: undefined ()
aws-amplify/storage: undefined ()
aws-amplify/storage/s3: undefined ()
aws-amplify/storage/s3/server: undefined ()
aws-amplify/storage/server: undefined ()
aws-amplify/utils: undefined ()
firebase: ^10.8.0 => 10.8.0
firebase/analytics: undefined ()
firebase/app: undefined ()
firebase/app-check: undefined ()
firebase/auth: undefined ()
firebase/auth/cordova: undefined ()
firebase/auth/web-extension: undefined ()
firebase/compat: undefined ()
firebase/compat/analytics: undefined ()
firebase/compat/app: undefined ()
firebase/compat/app-check: undefined ()
firebase/compat/auth: undefined ()
firebase/compat/database: undefined ()
firebase/compat/firestore: undefined ()
firebase/compat/functions: undefined ()
firebase/compat/installations: undefined ()
firebase/compat/messaging: undefined ()
firebase/compat/performance: undefined ()
firebase/compat/remote-config: undefined ()
firebase/compat/storage: undefined ()
firebase/database: undefined ()
firebase/firestore: undefined ()
firebase/firestore/lite: undefined ()
firebase/functions: undefined ()
firebase/installations: undefined ()
firebase/messaging: undefined ()
firebase/messaging/sw: undefined ()
firebase/performance: undefined ()
firebase/remote-config: undefined ()
firebase/storage: undefined ()
react: ^18.2.0 => 18.2.0
react-dom: ^18.2.0 => 18.2.0
react-hot-toast: ^2.4.1 => 2.4.1
react-scripts: 5.0.1 => 5.0.1
uuid: ^9.0.1 => 9.0.1 (8.3.2)
web-vitals: ^2.1.4 => 2.1.4
npmGlobalPackages:
@aws-amplify/cli: 12.10.0
http-server: 14.1.1
Describe the bug
I am using both in-app and push notification on a react native and a react webapp. Of course the push notification on react web app is not don eusing amplify since it is not supported, but I wired it manually using firebase and a lamda that proxy a call to pinpoint updateEndpoint API. When using the api of updateUser from aws-amplify/in-app-messaging or from aws-amplify/push-notifications both api even if returning success, fail to internally update pinpoint fields that a direct call to pinpoint updateEndpoint API successfully update. These fields are: demographic.locale demographic.timezone location.latitude location.longitude location.city location.country location.postalCode location.region
Expected behavior
All these field should be correctly populating the Pinpoint internal database. Else not campaign targeting these field will work
Reproduction steps
follow direction to install and configure ether amplify push notification on react native, or in-app notifications in ether react or react-native. Then, invoke identifyUser in ether in-app or push-notifications. make sure you populate the demographic and location that are reported buggy. And then go to pinpoint console, segment, export segment. THen look at the excelsheet, and see that all the boggus fields are indeed blank. I have verified that directly invoking pinpoint updateEndpoint API , I correctly populate these fields and they do show up on the exported endpoints collected as mentioned above via pinpoint console.
Code Snippet
// Put your code below this line.
mport React , {useState,useEffect} from 'react';
import {fetchUserAttributes} from '@aws-amplify/auth'
import { Authenticator, useAuthenticator} from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import {syncMessages, identifyUser} from 'aws-amplify/in-app-messaging'
import {withInAppMessaging} from '@aws-amplify/ui-react-notifications'
import Dashboard from './dashboard/Dashboard.js'
import Notification from './components/Notification'
import {v4 as uuidv4} from 'uuid'
import {generateClient} from 'aws-amplify/api'
import {pinpointGateway} from "./graphql/mutations"
const client = generateClient()
function App() {
const { user } = useAuthenticator((context) => [context.user]);
const { route } = useAuthenticator((context) => [context.route]);
console.log("user",user)
console.log("route", route)
const [userDetails, setUserDetails] = useState(null);
const [errorMessage, setErrorMessage] = useState(null)
const [pushToken, setPushToken] = useState(null)
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const errorDescription = params.get('error_description');
if (errorDescription) {
setErrorMessage(errorDescription.startsWith("PreSignUp failed with error . ")?errorDescription.substring(30):errorDescription);
}
}, []);
useEffect(() => {
const fetchUserDetails = async () => {
try {
const userData = await fetchUserAttributes();
setUserDetails(userData);
// Now userDetails contains more detailed information
} catch (error) {
console.error('Error fetching user details', error);
}
};
if (route === "authenticated") fetchUserDetails();
else setUserDetails(null)
}, [route]);
useEffect(()=>{
const identifyUserInput = async () => {
let location = {}
if (navigator.geolocation){
navigator.geolocation.getCurrentPosition((position)=>{
location = {latitude: position.coords.latitude,
longitude: position.coords.longitude
}
}, (error)=>{
console.log("Location permission denied")
})
} else{
console.log("Geolocation is not supported by this browser.")
}
return {
userId: userDetails.sub,
userProfile: {
email: userDetails.email,
name: userDetails.name,
plan:'myplan',
customProperties:{
hobbies: ["paintball", "bridge"] //~~EO todo
}
},
demographic:{
appVersion: "1.0.0",
locale: navigator.language.replace("-","_"), //~~EO todo add what we support as filter
make: navigator.vendor,
model: navigator.appCodeName,
modelVersion: navigator.appVersion.substring(0,50),
platform: navigator.platform,
platformVersion: "",
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
},
location: {
latitude: 10.12345,//location.latitude,
longitude: -2.12345,//location.longitude,
city: "Tomball",
country:"US",
postalCode:"77377",
region:"TEXAS",
},
metrics:{
// you app specific metrics todo
},
options:{
address: userDetails.email, //E.g. A device token or email address
optOut:"NONE", //Either ALL or NONE
userAttributes: {
interests: ['belotte','rami']
}
}
}
}
const dealWithPushNotification = async ()=>{
const identifiedUserInput =await identifyUserInput()
console.log("identified user:",identifiedUserInput)
await identifyUser(identifiedUserInput)
if (pushToken !== 'error') {
const res= await client.graphql({
query: pinpointGateway,
variables:{
functionName: "updateEndpoint",
functionParams:JSON.stringify(
{EndpointId: "test",
EndpointRequest:{
Demographic:{
AppVersion: identifiedUserInput.demographic.appVersion,
Locale: identifiedUserInput.demographic.locale,
Make: identifiedUserInput.demographic.make,
Model: identifiedUserInput.demographic.model,
ModelVersion: identifiedUserInput.demographic.modelVersion,
Platform: identifiedUserInput.demographic.platform,
PlatformVersion: identifiedUserInput.demographic.platformVersion,
Timezone: identifiedUserInput.demographic.timezone
},
Location: {
Latitude: identifiedUserInput.location.latitude,
Longitude: identifiedUserInput.location.longitude,
City: identifiedUserInput.location.city,
Country:identifiedUserInput.location.country,
PostalCode:identifiedUserInput.location.postalCode,
Region:identifiedUserInput.location.region,
},
Metrics: identifiedUserInput.metrics,
Address: pushToken,
OptOut: "NONE",
Attributes: {
email:[identifiedUserInput.userProfile.email],
name: [identifiedUserInput.userProfile.name],
plan: [identifiedUserInput.userProfile.plan],
...identifiedUserInput.userProfile.customProperties
},
User:{
UserId: identifiedUserInput.userId,
UserAttributes: identifiedUserInput.options.userAttributes
},
RequestId: uuidv4()
}
})
},
authMode: "iam"
})
console.log(res)
}
syncMessages()
console.log("DONE")
}
if (userDetails && pushToken) dealWithPushNotification()
},[userDetails,pushToken])
const clearErrorAndRefresh = () => {
window.location.href = window.location.pathname;
};
// If there is an error, display a separate UI
if (errorMessage) {
return (
<div style={{display:"flex", justifyContent:"center", alignItems:"center", height:"100vh", width:"100vw"}}>
<div className="amplify-flex amplify-alert amplify-alert--error" role="alert" style={{width:"450px", backgroundColor:"#fce9e9"}}>
<span className="amplify-alert__icon">
<span className="amplify-icon" aria-hidden="true" style={{width: "1em", height: "1em"}}>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM13 17H11V15H13V17ZM13 13H11V7H13V13Z" fill="currentColor">
</path>
</svg>
</span>
</span>
<div style={{flex: "1 1 0%"}}>
<div className="amplify-alert__body">{errorMessage}</div>
</div>
<button aria-label="Dismiss alert" className="amplify-button amplify-field-group__control amplify-button--link amplify-alert__dismiss" type="button" onClick={clearErrorAndRefresh} >
<span className="amplify-icon" aria-hidden="true" style={{width: "1em",height: "1em"}}>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z" fill="currentColor"></path>
</svg>
</span>
</button>
</div>
</div>
);
}
return (
<Authenticator>
{({ signOut, user }) => {
console.log("user",user)
console.log("userDetails",userDetails)
return (<>
<Notification pushTokenCallback={setPushToken}/>
<Dashboard signOut={signOut} user={user}/>
</>)}}
</Authenticator>
);
}
export default withInAppMessaging(App);
### Log output
<details>
// Put your logs below this line
</details>
### aws-exports.js
_No response_
### Manual configuration
_No response_
### Additional configuration
_No response_
### Mobile Device
_No response_
### Mobile Operating System
_No response_
### Mobile Browser
_No response_
### Mobile Browser Version
_No response_
### Additional information and screenshots
_No response_
Hello, @ericowhadi and sorry to hear your'e running into this. Can you clarify if this is being experienced with Apple Push Notification service (APNs), Firebase Cloud Messaging (FCM), or both? Also, can you double check that the required credentials have been input for your desired service channel within the Pinpoint console? Should be able to verify this under the project > Configure features > Push Notifications > service provider.
the issue exist on both APNs and FCM and on in-app messaging (both react native and react). The credentials are OK and correct, as all other information provided in identifyUser are making it correctly to pinpoint. only all location info, plus locale and timezone from demographic are not transmitted.
note that for APN, I have not yet enabled APNs backend, but the identifyUser workflow is independent of the push notification service provider. Service provider is important to receive the token, and then the identify user update the pinpoint Endpoint with the token in the address field. on Apple, because I don't yet have my DUNS number to create a valid apple developper account that can enable the APN service I have not tested really end to end. However, I know it fails because calling the IdentifyUser with a fake token does correctly update the Endpoint with the fake token, along with many other attributes, except the failed ones.
update, actually, after more testing, it is more than I previously said. All the demographic values are wrong (not populated). I saw that looking at android push notification from both emulator and real device pixel 7, none of the data about demographics gets updated, and for both device I am getting the same values in pinpoint: Default values: Demographic.ModelVersion: 34 Demographic.AppVersion: android/34 Demographic.Platform: android
Hi @ericowhadi, thanks for providing the code snippet. I notice that the demographic, metrics and location object blocks are outside the userProfile
block in your identifyUserInput
. Can you move inside and see if you still face the problem?
It should be as shown in the docs: https://docs.amplify.aws/javascript/build-a-backend/more-features/in-app-messaging/identify-user/
For a quick review:
const identifyUserInput = {
userId: '', // E.g. user-id
userProfile: {
email: '', // E.g. [email protected]
name: '', // E.g. name-of-the-user
plan: '' // E.g. plan-they-subscribe-to
customProperties: {
// E.g. hobbies: ['cooking', 'knitting'],
},
demographic: {
appVersion: '',
locale: '', // E.g. en_US
make: '', // E.g. Apple
model: '', // E.g. iPhone
modelVersion: '', // E.g. 13
platform: '', // E.g. iOS
platformVersion: '', // E.g. 15
timezone: '' // E.g. Americas/Los_Angeles
},
location: {
city: '', // E.g. Seattle
country: '', // E.g. US,
postalCode: '', // E.g. 98121
region: '', // E.g. WA
latitude: 0.0,
longitude: 0.0
},
metrics: {
// E.g. logins: 157
},
},
};
@Samaritan1011001 oops, my bad, I should be more careful following the docs. Sorry again, and thanks for catching my mistake. After correcting it everything works as expected.