Closed robert-ngo closed 5 years ago
It seems to be a false alarm.
The PushNotification.onRegister()
does get called but in different pattern:
.onRegister()
all the time, multiple times.onRegister()
once only, when the app/device is completely new. The calls afterwards seems to load from cached? Is it an expected behaviour?
I'm trying to dig deeper into the @aws-amplify/pushnotification
trying to understand this...
@RobertNg1125 thanks for your feedback, I will try to reproduced this problem and let you know.
@RobertNg1125 It is an expected behavior for Android because the device token should only be registered to Pinpoint service when:
Unfortunately there is no public API to get the device token manually. A work around is to read the token from the AsyncStorage as it's cached by this line: https://github.com/aws-amplify/amplify-js/blob/master/packages/pushnotification/src/PushNotification.ts#L236
@elorzafe @powerful23 Thanks for replying.
Yes, my workaround has been storing the device token using AsyncStorage. It was a bit confusing to me the way it got call multiple times on iOS and once on Android, wish it'll be documented somewhere.
@RobertNg1125 I have created a new app from scratch (iOS 9.0) onRegister
is called only the first time the app runs on the device.
There are my dependencies:
{
"@aws-amplify/pushnotification": "^1.0.22",
"aws-amplify": "^1.1.19",
"react": "16.6.3",
"react-native": "0.57.8"
}
I tested sending messages to the device token of the app and that works as expected.
I had a lot of trouble getting the token on my real Android device and thought I'd share how I found and tested it.
adb reverse tcp:9090 tcp:9090
to get your phone connectedreact-native run-android
@elorzafe for me the token does not get even to the asyncStorage, it is just not there... I was debugging it and I see that token is received in java part, but never get into RN part...
@dusan-dragon it does have some issue when the asyncStorage is cleaned and we will look into that. Can you please describe what you are going to do with this device token?
@powerful23 I just wanted to test push notifications, but because I did not know device token I could not send a notification from the AWS Pinnpoint and onRegister method was appearing not working, because if you will console.log() the token in react-native app, you will probably never see it because onRegister method is called only once after the app is installed and you will not have debugger connected at that time... so the only other way was to read it from AsyncStorage, but it is empty, it is empty when you do not set Analytics module (which I did not because I do not want the analytics...)
it would be great if the library exposed a method to get the token for exactly the reason @powerful23 states
docs at https://aws-amplify.github.io/docs/js/push-notifications should be updated for android, especially app/build.gradle dependencies to reflect Firebase's docs.
@powerful23 How did you read device token from AsyncStorage
?
@dusan-dragon How did you find token in Java part? I see in Logical in Android studio only FCM message id:
Logging event (FE): notification_open(_no), Bundle[{firebase_event_origin(_o)=fcm, message_device_time(_ndt)=0, message_time(_nmt)=1555314333, message_id(_nmid)=5461448130273880619}]
@Luckygirlllll see the merged code: https://github.com/aws-amplify/amplify-js/pull/2916/files#diff-5a56ffa68b87bbf8cfbc99c7aa076171R67 and if you do not want to change it in code, you can search in Android Studio logcat for a tag RNPushNotificationDeviceIDService
and you should see Refreshed token
I sent test Message from AWS Pinpoint
console using device token (which I got in Android studio logcal), it says that message was sent successfully, but I didn't receive anything on the device.
@powerful23 Why this issue was closed? What is the solution for this problem? onRegister
still doesn't work, it's not possible to send Push notifications to android devices.
@Luckygirlllll it should work (because you got the token) but the thing is if you put the console.log() in onRegister()
call you will never see it because on android it gets called only once right after the app is installed and first time opened... Also you will not see any notification if you have app opened in foreground... make sure that you close the app before sending the notification
@dusan-dragon I know that app shouldn't be in the foreground, my app is closed, I'm not receiving Push notification on real device from AWS Pinpoint
, even though I see in the AWS Pinpoint
console: "Successfully sent push notification". @saadq is having the same issue.
I don't see that onRegister
method was ever triggered in the app, I uninstalled the app, and trying to save token in the AsyncStorage
in onRegister
, when, I want to get the token from AsyncStorage
I'm getting null
.
I have latest version of aws-amplify
and aws-amplify/pushnotification
"@aws-amplify/pushnotification": "^1.0.25"
"aws-amplify": "^1.1.26",
Just confirming that I did it when the app was NOT in the foreground. It still didn't work when using Pinpoint, but sending a test notification from the Firebase console DID work. I am also on the latest version of @aws-amplify/pushnotification
(but an older version of aws-amplify
, which is 1.1.8
).
@Luckygirlllll @saadq this could be related to #2975
If the device token is valid, you should receive a notification. The onRegister
callback will only be triggered when the token is generated/updated so normally it's only called when the app is installed/first opened.
Could you double check if something like RNPushNotificationMessagingService: Message From: ${senderId}
in the Android log when sending the notification so that we can find out whether the notification is received in local or not?
@powerful23 I don't see anything in logcat after sending Push notification from AWS Pinpoint
console.
@powerful23 I still can’t get token in onRegister method, the only one way how I got token was through Java code.
@Luckygirlllll @saadq I did some fix in the pushnotification package. The fix is to ensure device token is cached correctly in the local. Can you try it with your app? You can run:
yarn install aws-amplify@unstable
yarn install @aws-amplify/pushnotification@unstable
To make sure the endpoint is updated with the device token, you can put window.LOG_LEVEL='DEBUG'
in the App.js
and after starting the app, you should see AWSPinpointProvider - updateEndpoint with params: ...
in your console log.
Sure, I will try it out by today or tomorrow and let you know how it goes!
Apologies for the delay.
So I set the log level to 'DEBUG'
, and I'm noticing some strange things, and I think I am facing some issues with updateEndpoint()
because I am using a manual config instead of using Amplify CLI.
I only call updateEndpoint()
once in my code after sign in, but there seem to be multiple AWSPinpointProvider - updateEndpoint with params: ...
calls showing up in my JS logs, with some not having any correct info like UserAttributes:
[12:59:07] [DEBUG] 59:05.888 AWSPinpointProvider - updateEndpoint with params: Object { [12:59:07] "ApplicationId": "f0eb5d745d374bb7a7e493b1735d3dad", [12:59:07] "EndpointId": "059c4870-61f9-11e9-923c-eb372d07f776", [12:59:07] "EndpointRequest": Object { [12:59:07] "Attributes": Object {}, [12:59:07] "ChannelType": undefined, [12:59:07] "Demographic": Object { [12:59:07] "AppVersion": "android/28", [12:59:07] "Make": undefined, [12:59:07] "Model": undefined, [12:59:07] "ModelVersion": "28", [12:59:07] "Platform": "android", [12:59:07] }, [12:59:07] "EffectiveDate": "2019-04-18T16:59:05.888Z", [12:59:07] "Location": Object {}, [12:59:07] "Metrics": Object {}, [12:59:07] "RequestId": "...", [12:59:07] "User": Object { [12:59:07] "UserAttributes": Object {}, [12:59:07] "UserId": "...", [12:59:07] }, [12:59:07] }, [12:59:07] }
[13:00:22] [DEBUG] 59:25.830 AWSPinpointProvider - updateEndpoint with params: Object { [13:00:22] "ApplicationId": "...", [13:00:22] "EndpointId": "...", [13:00:22] "EndpointRequest": Object { [13:00:22] "Address": "...", [13:00:22] "Attributes": Object {}, [13:00:22] "ChannelType": "GCM", [13:00:22] "Demographic": Object { [13:00:22] "AppVersion": "0.0.15", [13:00:22] "Make": undefined, [13:00:22] "Model": undefined, [13:00:22] "ModelVersion": "28", [13:00:22] "Platform": "android", [13:00:22] }, [13:00:22] "EffectiveDate": "2019-04-18T16:59:25.829Z", [13:00:22] "Location": Object {}, [13:00:22] "Metrics": Object {}, [13:00:22] "RequestId": "...", [13:00:22] "User": Object { [13:00:22] "UserAttributes": Object { [13:00:22] "email": Array [ [13:00:22] "...", [13:00:22] ], [13:00:22] "email_verified": Array [ [13:00:22] "true", [13:00:22] ], [13:00:22] "name": Array [ [13:00:22] "...", [13:00:22] ], [13:00:22] "sub": Array [ [13:00:22] "...", [13:00:22] ], [13:00:22] }, [13:00:22] "UserId": "...", [13:00:22] }, [13:00:22] }, [13:00:22] }
I also see multiple fail responses in the logs like so:
[12:59:07] [DEBUG] 59:06.135 AWSPinpointProvider - updateEndpoint failed [BadRequestException: Exceeded maximum endpoint per user count 10]
Along with some warnings like:
Please ensure you have updated your Pinpoint IAM Policy with the Action: "mobiletargeting:GetUserEndpoints" in order to get endpoints info of the user
As for my Android logs, here are some relevant logs for the push notifications:
I/ReactNativeJS: '[DEBUG] 49:29.330 Notification - update endpoint in push notification', '...token...'
I/ReactNativeJS: [DEBUG] 49:29.347 Notification - update endpoint success, setting token into cache
2019-04-18 12:49:29.330 30367-30534/com.investroo.zoya I/ReactNativeJS: '[DEBUG] 49:29.330 Notification - update endpoint in push notification', '...token...'
2019-04-18 12:49:29.344 30367-30534/com.investroo.zoya I/ReactNativeJS: '[DEBUG] 49:29.343 Notification - refresh the device token with', '...different token value...'
2019-04-18 12:49:29.347 30367-30534/com.investroo.zoya I/ReactNativeJS: [DEBUG] 49:29.347 Notification - update endpoint success, setting token into cache
2019-04-18 12:49:29.365 30367-30534/com.investroo.zoya I/ReactNativeJS: '[DEBUG] 49:29.364 AWSPinpointProvider - endpointId from cache', [ '...endpoint-id...', 'type', 'string' ]
2019-04-18 12:49:29.366 30367-30534/com.investroo.zoya I/ReactNativeJS: '[DEBUG] 49:29.366 AWSPinpointProvider - setting endpoint id from the cache', '...endpoint-id...'
2019-04-18 12:49:29.367 30367-30534/com.investroo.zoya I/ReactNativeJS: '[DEBUG] 49:29.366 Hub - Dispatching to analytics with ', { event: 'pinpointProvider_configured', data: null }
2019-04-18 12:49:29.367 30367-30534/com.investroo.zoya I/ReactNativeJS: '[DEBUG] 49:29.367 Analytics - on hub capsule analytics', { event: 'pinpointProvider_configured', data: null }
2019-04-18 12:59:01.005 32113-32285/com.investroo.zoya I/RNPushNotificationModule: getting tokenf3m...
2019-04-18 12:59:01.019 32113-32284/com.investroo.zoya I/ReactNativeJS: '[DEBUG] 59:01.19 Notification - Get the token from Firebase Service', 'f3m...'
2019-04-18 12:59:01.019 32113-32284/com.investroo.zoya I/ReactNativeJS: '[DEBUG] 59:01.19 Notification - update endpoint in push notification', 'f3m...'
2019-04-18 12:59:01.025 32113-32284/com.investroo.zoya I/ReactNativeJS: '[DEBUG] 59:01.25 AuthClass - failed to get or parse item aws-amplify-federatedInfo', { [SyntaxError: JSON Parse error: Unexpected identifier "undefined"]
I think I'm going to try to fix updateEndpoint()
first before I try to pursue fixing push notifications.
EDIT: I forgot to mention, I'm still having the same issue. I get a message saying that the notification was successfully sent, but I don't get anything on my device, even though the app is not in the foreground. Additionally, I still don't see any RNPushNotificationMessagingService: Message From
message when I send the notification.
Will probably move this to another issue, but I am still kind of confused about updateEndpoint
. The AWS docs within the pinpoint console seem to suggest this kind of syntax:
But the Amplify docs seem to lowercase/camelcase everything instead of PascalCase like above:
Analytics.updateEndpoint({
address: 'xxxxxxx', // The unique identifier for the recipient. For example, an address could be a device token, email address, or mobile phone number.
attributes: {
// Custom attributes that your app reports to Amazon Pinpoint. You can use these attributes as selection criteria when you create a segment.
hobbies: ['piano', 'hiking'],
},
channelType: 'APNS', // The channel type. Valid values: APNS, GCM
demographic: {
appVersion: 'xxxxxxx', // The version of the application associated with the endpoint.
locale: 'xxxxxx', // The endpoint locale in the following format: The ISO 639-1 alpha-2 code, followed by an underscore, followed by an ISO 3166-1 alpha-2 value
make: 'xxxxxx', // The manufacturer of the endpoint device, such as Apple or Samsung.
model: 'xxxxxx', // The model name or number of the endpoint device, such as iPhone.
modelVersion: 'xxxxxx', // The model version of the endpoint device.
platform: 'xxxxxx', // The platform of the endpoint device, such as iOS or Android.
platformVersion: 'xxxxxx', // The platform version of the endpoint device.
timezone: 'xxxxxx' // The timezone of the endpoint. Specified as a tz database value, such as Americas/Los_Angeles.
},
location: {
city: 'xxxxxx', // The city where the endpoint is located.
country: 'xxxxxx', // The two-letter code for the country or region of the endpoint. Specified as an ISO 3166-1 alpha-2 code, such as "US" for the United States.
latitude: 0, // The latitude of the endpoint location, rounded to one decimal place.
longitude: 0, // The longitude of the endpoint location, rounded to one decimal place.
postalCode: 'xxxxxx', // The postal code or zip code of the endpoint.
region: 'xxxxxx' // The region of the endpoint location. For example, in the United States, this corresponds to a state.
},
metrics: {
// Custom metrics that your app reports to Amazon Pinpoint.
},
/** Indicates whether a user has opted out of receiving messages with one of the following values:
* ALL - User has opted out of all messages.
* NONE - Users has not opted out and receives all messages.
*/
optOut: 'ALL',
// Customized userId
userId: 'XXXXXXXXXXXX',
// User attributes
userAttributes: {
interests: ['football', 'basketball', 'AWS']
// ...
}
})
Other than that, my main confusion on why the logs are showing updateEndpoint called multiple times with different params... I'm wondering if doing Analytics.configure({ ... })
automatically calls updateEndpoint() for you with mostly empty/undefined values.
@powerful23 I can see in debug, that there is device token, however, onRegister()
method still doesn't work, I'm saving inside onRegister device token, when I want to get device token in another component , device token is always null. I also was trying to get device token through AsyncStorage
by calling: await AsyncStorage.getItem("push_tokenXXXX")
, where XXXXX is my App_Id
, however, it was still null.
Here what I see in logs:
[DEBUG] 50:38.726 Notification - Get the token from Firebase Service xxxx [DEBUG] 50:38.729 Notification - update endpoint in push notification xxxx [DEBUG] 50:38.741 Notification - refresh the device token with xxxx [DEBUG] 50:38.742 Notification - Analytics module is not registered into Amplify [DEBUG] 50:38.748 AWSPinpointProvider - endpointId from cache Array [ "842bfc90-62a2-11e9-9828-41b0e10cc7xx", "type", "string", ] [DEBUG] 50:38.756 AWSPinpointProvider - setting endpoint id from the cache 842bfc90-62a2-11e9-9828-41b0e10cc7xx AWSPinpointProvider - setting endpoint id from the cache xxxx Hub - Dispatching to analytics with Object { "data": null, "event": "pinpointProvider_configured", } [DEBUG] 59:58.595 Analytics - on hub capsule analytics Object { "data": null, "event": "pinpointProvider_configured", } [DEBUG] 59:58.664 Notification - refresh the device token with
I can confirm that problem is still exist, I can't never get device token in JS code, and when I'm sending test PN from AWS Pinpoint console, I'm not getting PN on the device, even though I see message that it was sent successfully
@saadq
I only call updateEndpoint() once in my code after sign in, but there seem to be multiple AWSPinpointProvider - updateEndpoint with params: ... calls showing up in my JS logs, with some not having any correct info like UserAttributes:
This is caused by the auto session recording feature in the analytics module. It will automatically update the endpoint and send session start/stop events when the app is opened/reloaded/closed. You can turn it off by setting autoSessionRecord
to false
: https://aws-amplify.github.io/docs/js/analytics#manual-setup
I also see multiple fail responses in the logs like so: [12:59:07] [DEBUG] 59:06.135 AWSPinpointProvider - updateEndpoint failed [BadRequestException: Exceeded maximum endpoint per user count 10]
This error is caused because of the limitation of Pinpoint. In pinpoint each user id
can only be mapped to at most 10 endpoint id
. The endpoint id is generated automatically by Amplify using uuid
and cached in local. If the cache is removed very often, then it will generate a lot of endpoint ids which are mapped to the same user id. The way to avoid this error is to follow the advice in the warning to add that policy in your IAM and then Amplify can remove those unused endpoint ids for you.
Will probably move this to another issue, but I am still kind of confused about updateEndpoint. The AWS docs within the pinpoint console seem to suggest this kind of syntax:
The AWS docs in the Pinpoint console is outdated. Please follow the Amplify docs. I will also raise this to the Pinpoint team.
@Luckygirlllll
[DEBUG] 50:38.742 Notification - Analytics module is not registered into Amplify
Analytics module is needed to update the endpoint with the device token and only after that happens the device token will be cached in AsyncStorage. Can you paste the dependencies of package.json
here? Also please make sure there is no node_modules
under node_modules/@aws-amplify/pushnotification/
@powerful23 "dependencies": {
"@aws-amplify/pushnotification": "^1.0.26-unstable.3",
"@expo/vector-icons": "^10.0.1",
"aws-amplify": "^1.1.27-unstable.4",
"expo": "^32.0.0",
"expokit": "^32.0.7",
"moment": "^2.24.0",
"moment-duration-format": "^2.2.2",
"react": "16.5.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
"react-native-datepicker": "^1.7.2",
"react-native-wheel-picker-android": "^2.0.5",
"react-navigation": "^3.2.1",
"react-redux": "^6.0.1",
"redux": "^4.0.1",
"redux-promise": "^0.6.0",
"redux-saga": "^1.0.1",
"reduxsauce": "^1.0.1",
"seamless-immutable": "^7.1.4"
``` }
I also want to add, that in my case` IOS` project works as expected, problem only with `Android `
@powerful23 there is no node_modules
under node_modules/@aws-amplify/pushnotification/
@Luckygirlllll cool. And how did you import Amplify etc in your App? Can you provide some code snippets?
@powerful23 Yes, sure! Here is my code:
import Amplify, { Auth, Analytics } from 'aws-amplify'
import PushNotification from '@aws-amplify/pushnotification'
Amplify.configure({
Auth: {
region: 'us-east-1',
userPoolId: 'us-east-1_xxx',
userPoolWebClientId: 'xxx',
identityPoolId: 'us-east-1:xxx',
mandatorySignIn: true
},
API: {
endpoints: [{
name: "xxx",
endpoint: "https://xxx",
custom_header: async () => ({ Authorization: await getAuthorizationToken() })
}]
},
Analytics: {
disabled: false,
AWSPinpoint: {
appId: 'xxx',
region: 'us-east-1',
}
}
});
Analytics.configure({
appId: 'xxx',
});
PushNotification.configure({
appId: 'xxx',
region: 'us-east-1',
});
export default class App extends React.Component {
componentDidMount(){
PushNotification.onNotification((notification) => {
notification.finish(PushNotificationIOS.FetchResult.NoData);
});
PushNotification.onRegister((token) => {
AsyncStorage.setItem('deviceToken', token);
});
PushNotification.onNotificationOpened((notification) => {
console.log('the notification is opened', notification);
});
}
and then when I'm trying to update endpoint after Sign in:
`import Analytics from '@aws-amplify/analytics'`
`export default class SignInScreen extends React.Component {`
signIn =async () => {
var deviceToken = await AsyncStorage.getItem("deviceToken");
await Analytics.updateEndpoint({
address: deviceToken,
userId: "1",
})
}
}
I am having the same issue on Android, on register event never gets called. iOS works as expected
"dependencies": { "@aws-amplify/pushnotification": "^1.0.25", "aws-amplify": "^1.1.26", "aws-amplify-react-native": "^2.1.10", "react": "16.6.3", "react-native": "^0.57.8", "react-native-dropdown-menu": "^2.0.0", "react-native-input-scroll-view": "^1.8.0", "react-native-keyboard-aware-scroll-view": "^0.8.0", "react-native-keyboard-listener": "^1.1.0", "react-native-loading-spinner-overlay": "^1.0.1", "react-native-modest-checkbox": "^3.1.0", "react-native-navigation": "^2.11.0", "react-native-phone-call": "^1.0.9", "react-native-pie": "^0.1.0", "react-native-pie-chart": "^1.0.13", "react-native-popup-menu": "^0.15.4", "react-native-progress": "^3.5.0", "react-native-progress-circle": "^2.0.1", "react-native-segmented-control-tab": "^3.4.0", "react-native-tabbar-navigator": "^0.4.3", "react-native-vector-icons": "^6.2.0", "react-navigation": "^3.2.3", "react-redux": "^6.0.0", "redux": "^4.0.1" },
@Luckygirlllll that's weird. Both the package.json and the code look fine to me. Because the pushnotifacation module will internally update the endpoint with the device token and after that it will cache the device token into local.
But if you still see [DEBUG] 50:38.742 Notification - Analytics module is not registered into Amplify
in the debug log, then it will won't trigger that action and thus no device token cached in storage.
Can you please try removing the node modules and do a reinstall again?
I removed aws-pushnotifications and switched to OneSignal.
If anyone else is running into this I fixed it by setting the token directly from the firebase method like so:
if (Platform.OS !== 'ios') {
// grab token
const deviceToken = await firebase.messaging().getToken();
console.log('Firebase device token: ', deviceToken);
if (deviceToken) {
await configurePinpoint(deviceToken, userId);
} else {
console.log('There was an error getting the device token');
}
}
}
const configurePinpoint = async(token, userId) => {
console.log('Configuring pinpoint');
// Configure analytics endpoint for user
Analytics.updateEndpoint({
address: token, // The unique identifier for the recipient. For example, an address could be a device token, email address, or mobile phone number.
channelType: Platform.OS === 'ios' ? 'APNS' : 'GCM', // The channel type. Valid values: APNS, GCM
// Customized userId
userId: userId,
optOut: 'NONE'
});
For me, the issue seemed like the on register never saved the token on android.
This is my workaround if you need the token:
PushNotification.onRegister(async (token) => { await AsyncStorage.setItem('@pushNotificationToken', token) console.log('in app registration', token); });
the problem is that on android the method above executes just the first time, to get this token later use AsyncStorage
Thanks @Luckygirlllll . Literally took 30 mins to switch to onesignal after 5+ hours of debugging and getting nowhere with Amplify/Pinpoint.
Submitted a new issue regarding the same issue. onRegister is not working for iOS but working fine for android. As stated, followed the documentation on setting up for both platform.
same issue on android with onRegister, for ios it works fine.
dependencies: "@aws-amplify/pushnotification": "^3.2.28", "aws-amplify": "^3.3.22",
I had to use this code in order to get device token on Android:
import { NativeModules } from 'react-native'
NativeModules.RNPushNotification.getToken((token) => console.log('token', token))
reference: https://github.com/aws-amplify/amplify-js/issues/2643#issuecomment-523610933
This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.
Looking for a help forum? We recommend joining the Amplify Community Discord server *-help
channels or Discussions for those types of questions.
Hi,
I'd want to use method
PushNotification.onNotificationOpened()
which seems to be available only at 1.0.20 or later. However, after upgrading "@aws-amplify/pushnotification" to 1.0.20, myPushNotification.onRegister()
no longer got called. I no longer can print out the device token.I followed instructions at https://aws-amplify.github.io/docs/js/push-notifications and could confirm that the system was working with "@aws-amplify/pushnotification@1.0.19"
Anyone has successfully implemented
PushNotification.onNotificationOpened()
on react-native application?Thanks for your input,
My dependencies: