Testing Push Notifications with AWS Amplify & CLI

Daniel Dantas (@dantasfiles)
5 min readJan 14, 2020

--

In this post, we test sending push notifications to an AWS Amplify React Native app with the AWS CLI.

The example code for this post uses React Native 61.5 and AWS Amplify 2.2.2, and is at https://github.com/dantasfiles/AmplifyAndroidPush

This post proceeds methodically so that you can verify your progress at each step. The examples use FCM and Android, but should work for APNS and iOS as well.

This post is part of a series:
- Setting up Android Push Notifications with AWS Amplify
- Testing Push Notifications with AWS Amplify & CLI
- Handling Incoming Push Notifications in AWS Amplify
- Customizing the Appearance of Android Push Notifications with AWS Amplify

Setup AWS CLI

If you haven’t already, Setup the AWS CLI: InstallSetup IAMConfigure

Record the AWS Pinpoint project id

First, we record the AWS Pinpoint project id. It can be found in either of two places — the first in aws-exports.js

// aws-exports.js
const awsmobile = {
"aws_mobile_analytics_app_id": "XXXXX",
};

Or in the Project ID field in the AWS Pinpoint console

Verify your push notification channels are enabled in your AWS Pinpoint project

Use the get-channels CLI command to retrieve information about the channels in your AWS Pinpoint application.

> aws2 pinpoint get-channels --application-id YOUR AWS PINPOINT PROJECT ID

The result should look something like:

{
"ChannelsResponse": {
"Channels": {
"GCM": {
"ApplicationId": "YOUR AWS PINPOINT PROJECT ID",
"CreationDate": "XXXX-XX-XXXXX",
"Enabled": true,
"HasCredential": true,
"Id": "gcm",
"IsArchived": false,
"LastModifiedDate": "XXXX-XX-XXXXX",
"Version": 1
}
}
}
}

Record the device endpoint

For testing purposes, we want to record the AWS Pinpoint endpoint of the device. Recall that “endpoint represents a destination that you can send messages to, such as a mobile device, email address, or phone number.” In App.js, we print this endpoint id to the console and to the app screen, making it easy to record for use in your later testing.

// App.js
const endpointId =
Analytics.getPluggable('AWSPinpoint')._config.endpointId;

Note: Only use this for testing. Do NOT use this in production code because it relies on AWS Amplify internals. If there’s a better way to get the endpoint id for testing, let me know.

Verify the device endpoint details from AWS Pinpoint

Run the app on your physical Android device, connected using a USB cable.
> npx react-native run-android

Then verify that your device endpoint now has the device push notification FCM token associated with it, using the get-endpoint CLI command with the previously recorded AWS Pinpoint project id and endpoint id.

> aws2 pinpoint get-endpoint --application-id YOUR AWS PINPOINT PROJECT ID --endpoint-id YOUR ENDPOINT ID

The result should look something like:

{
"EndpointResponse": {
"Address": "YOUR DEVICE FCM TOKEN",
"ApplicationId": "YOUR AWS PINPOINT PROJECT ID",
"ChannelType": "GCM",
"EndpointStatus": "ACTIVE",
"Id": "YOUR ENDPOINT ID",
"OptOut": "NONE",
...
}
}

Send a test push notification to the device

Create a file called pinpoint-send-messages.json

// pinpoint-send-messages.json
{
"ApplicationId": "YOUR AWS PINPOINT PROJECT ID",
"MessageRequest": {
"Endpoints": {
"YOUR ENDPOINT ID": {}
},
"MessageConfiguration": {
"DefaultPushNotificationMessage": {
"Body": "Test Body",
"Title": "Test Title"
}
}
}
}

Use the send-messages CLI command to send the test push notification to your device endpoint

> aws2 pinpoint send-messages --cli-input-json file://pinpoint-send-messages.json

Your phone will receive a push notification, and the result of the send-messages command should look something like:

{
"MessageResponse": {
"ApplicationId": "YOUR AWS PINPOINT PROJECT ID",
"EndpointResult": {
"YOUR ENDPOINT ID": {
"Address": "YOUR DEVICE FCM TOKEN",
"DeliveryStatus": "SUCCESSFUL",
}
},
}
}

At this point, you are now able to successfully send push notifications to selected devices.

User Id Discussion

The next step is to send a push notification to selected users.

When AWS Amplify sets up a new endpoint on a device, it associates it with the current identity pool id. This can cause two issues. First, the user may not have logged in yet when the endpoint is set up, so the identity pool id associated with the endpoint won’t be the identity pool id of the later logged-in user. Second, we often want to want to send push notifications to a user using a user pool attribute like their username or internal user id (sub), not their identity pool id.

As such, our example code will associate the device endpoint with a different userid string. Any string can be used as an endpoint’s user id, but you should use something that 1) is unique, and 2) stays constant over the lifetime of the user. Reasonable choices are the username or the unique user pool userid that’s stored in the sub field. In our example code, we’ll be associating the device endpoint with the sub internal userid.

We retrieve the AWS Cognito User Attributes for the current user using the Auth.currentUserInfo method, and pull out the unique internal userid, located in the sub field. For more information on the Auth.currentUserInfo method, see Retrieving user information from AWS Amplify authentication. In the example on Github, we print this user id to the console and to the app screen, making it easy to record for use in your later testing.

// App.js
const { attributes: {sub} } = await Auth.currentUserInfo();

Associate the device endpoint with the user id

The code then calls Analytics.updateEndpoint to associate the device endpoint with the sub internal userid.

// App.js
Analytics.updateEndpoint({userId: sub});

Verify that the endpoint was associated with your user

Run the app on your physical Android device, connected using a USB cable.
> npx react-native run-android

Run the get-user-endpoints CLI command with the previously recorded AWS Pinpoint project id and the user id.

> aws2 pinpoint get-user-endpoints --application-id YOUR AWS PINPOINT PROJECT ID --user-id YOUR USER ID 

The result should look something like:

{
"EndpointsResponse": {
"Item": [
{
"Address": "YOUR DEVICE FCM TOKEN",
"ApplicationId": "YOUR AWS PINPOINT PROJECT ID",
"ChannelType": "GCM",
"EndpointStatus": "ACTIVE",
"Id": "YOUR ENDPOINT ID",
"OptOut": "NONE",
"User": {
"UserId": "YOUR USER ID"
}
}
... OTHER ENDPOINTS IF ASSOCIATED
]
}
}

Send a push notification to all endpoints associated with your user

Create a pinpoint-send-users-messages.json file

// pinpoint-send-users-messages.json
{
"ApplicationId": "YOUR AWS PINPOINT PROJECT ID",
"SendUsersMessageRequest": {
"MessageConfiguration": {
"DefaultPushNotificationMessage": {
"Body": "Test Body",
"Title": "Test Title"
}
},
"Users": {
"YOUR USER ID": {}
}
}
}

Use the send-users-messages CLI command to send the test push notification to all endpoints associated with your user

> aws2 pinpoint send-users-messages --cli-input-json file://pinpoint-send-users-messages.json

Your phone will receive a push notification, and the result of the send-users-messages command should look something like:

{
"SendUsersMessageResponse": {
"ApplicationId": "YOUR AWS PINPOINT PROJECT ID",
"Result": {
"YOUR USER ID": {
"YOUR ENDPOINT ID": {
"Address": "YOUR DEVICE FCM TOKEN",
"DeliveryStatus": "SUCCESSFUL"
}
... OTHER ENDPOINTS IF ASSOCIATED
}
}
}
}

You now have verified that your push notifications are set up correctly.

--

--

Daniel Dantas (@dantasfiles)

I create guides to help me fully understand the issues that I’m encountering and fixing. Web: dantasfiles.com Email: daniel@dantasfiles.com