AWS News Blog

Push Notifications to Mobile Devices Using Amazon SNS

Voiced by Polly

Does your mobile app keep on running in the cloud, even when the associated smartphone or tablet is closed? If so, you might want to proactively provide your customers with useful information. For example, a traffic app can warn of heavy traffic and a slow commute, allowing the user to arrive in time for their first meeting of the day.

Push notifications are short, alert-style messages you can send to users even when they are not actively using your app. The experience is similar to SMS, but it costs much less because it uses Wi-Fi or cellular data. Users can choose to acknowledge a push notification to launch your app and see more information.

Implementing push notifications can be tricky, especially when you target multiple platforms such as iOS, Android and Kindle Fire. Many customers do it by integrating directly with the push relay services that Amazon, Apple, and Google provide for their devices. These services each use different, platform-specific APIs, and you have to manage things like token updates or token invalidation by the services, along with token feedback when users upgrade their devices or delete your app. Also, the nature of mobile app distribution is such that successful apps can become popular almost overnight. Scaling quickly from zero to millions of devices, and tens of millions of daily notifications, can be challenging.

Customers tell us that this is just the sort of undifferentiated heavy lifting they like us to solve on their behalf. Today, we are enhancing the Amazon Simple Notification Service with Mobile Push, a new feature that transmits push notifications from backend server applications to mobile apps on Apple, Google and Kindle Fire devices using a simple, unified API. You can send a message to a particular device (direct addressing), or you can send a message to every device that is subscribed to a particular SNS topic (broadcast).

Best of all, you can start using this feature at no charge. The AWS Free Tier means all AWS customers can send one million push notifications per month across iOS, Android and Kindle platforms at no charge. After that, you pay $0.50 for every million publishes and $0.50 per million push deliveries.

How it Works
Here’s what you need to do to create a mobile app that can receive push notifications:

  1. Create an app for a supported device and messaging API (Amazon Device Messaging, Apple Push Notification Service, or Google Cloud Messaging). The app must register with the local platform notification service using the device APIs in order to be able to receive notifications. For example, an iOS application would use the registerForRemoteNotificationTypes method. Although the specifics will vary from platform to platform, you will end up with some sort of token or identifier that is unique to the device. The code on the device will need to communicate this value to the server-side code. You could use an Amazon SQS queue or an SNS topic for this purpose.
  2. Create a server-side representation of the app using SNS’s CreatePlatformApplication function.
  3. Register devices as your server code becomes aware of them by calling the SNS CreatePlatformEndpoint function. This function will return an ARN (Amazon Resource Name) that uniquely identifies the device.
  4. Send messages directly to a specific device by calling the Publish function with the device’s ARN. You can easily scale this to handle millions of users by storing the endpoint ARNs in Amazon DynamoDB and using multi-threaded code on the server.
  5. Send messages to all devices subscribed to a topic by calling the same Publish function, but use the ARN of the topic. You can subscribe up to 10,000,000 devices to a single topic. For larger number of devices, use direct addressing as described in the previous step, or use multiple topics.

Mobile Messaging With PHP & Our Sample Application
In order to help you get started with this new feature as quickly as possible, we have put together a sample mobile push application. This application is provided in source code for all three of the supported platforms and messaging APIs.

I have an Android phone and used the AndroidMobilePushApp included in the ZIP file. Here’s the most interesting part of the code:


public class ExternalReceiver extends BroadcastReceiver
{
  @Override public void onReceive(Context context, Intent intent) {
    Log.i("ExternalReceiver","onReceive");
    Bundle extras = intent.getExtras();
    StringBuilder payload = new StringBuilder();
    for(String key : extras.keySet()){
      payload.append(String.format("%s=%s", key, extras.getString(key)) + '\n');
    }

    Intent newIntent = new Intent();
    newIntent.setClass(context, AndroidMobilePushApp.class);
    newIntent.putExtra(context.getString(R.string.msgfield), payload.toString());
    newIntent.setFlags(Intent.FLAGACTIVITYNEWTASK | Intent.FLAGACTIVITYSINGLE_TOP);
    context.startActivity(newIntent);
  }
} 

I used the newest version of the AWS SDK for PHP to write a simple application. My code lists all of the applications, all of the endpoints of the first application in the list, and then sends the message “Hello from PHP” to all of the endpoints. Here’s all it takes to do this:


#!/usr/bin/env php
 '...',
                                           'secret' => '...',
                                           'region' => 'us-east-1'));

  // Get and display the platform applications
  print("List All Platform Applications:\n");
  $Model1 = $sns->listPlatformApplications();
  foreach ($Model1['PlatformApplications'] as $App)
  {
    print($App['PlatformApplicationArn'] . "\n");
  }
  print("\n");

  // Get the Arn of the first application
  $AppArn = $Model1['PlatformApplications'][0]['PlatformApplicationArn'];

  // Get the application's endpoints
  $Model2 = $sns->listEndpointsByPlatformApplication(array('PlatformApplicationArn' => $AppArn));

  // Display all of the endpoints for the first application
  print("List All Endpoints for First App:\n");
  foreach ($Model2['Endpoints'] as $Endpoint)
  {
    $EndpointArn = $Endpoint['EndpointArn'];
    print($EndpointArn . "\n");
  }
  print("\n");

  // Send a message to each endpoint
  print("Send Message to all Endpoints:\n");
  foreach ($Model2['Endpoints'] as $Endpoint)
  {
    $EndpointArn = $Endpoint['EndpointArn'];
    try
    {
      $sns->publish(array('Message' => 'Hello from PHP',
                          'TargetArn' => $EndpointArn));
      print($EndpointArn . " - Succeeded!\n");
    }
    catch (Exception $e)
    {
      print($EndpointArn . " - Failed: " . $e->getMessage() . "!\n");
    }
  }
?>

Here’s what shows up on the phone after I ran this code a couple of times:

And here is what I saw on the console:

List All Platform Applications:
arn:aws:sns:us-east-1:348414629041:app/GCM/Amazon_Mobile_Push
List All Endpoints for First App:
arn:aws:sns:us-east-1:348414629041:endpoint/GCM/Amazon_Mobile_Push/dc8a5ae9-2f21-33a2-a8cd-7fafba642bf4
Send Message to all Endpoints:
arn:aws:sns:us-east-1:348414629041:endpoint/GCM/Amazon_Mobile_Push/dc8a5ae9-2f21-33a2-a8cd-7fafba642bf4 - Succeeded!

Mobile Messaging From the Console
You can manage the entire process of creating an app and registering devices from the SNS tab of the AWS Management Console. Here’s a walkthrough.

Start by clicking the Add a New App button:

Enter the application’s name, choose a push platform, and enter and the credentials (in this case an API key for Google Cloud Messaging for Android) for the platform:

Optionally, configure a set of SNS topics for notification of significant events:

Then, register the endpoints using the tokens supplied by each user device that registers for your notification service:

You can then send notifications to the endpoints:

And the message will appear on the device (this is a screenshot of the sample app):

Go For It
The new Mobile Push section of the Amazon SNS Developer Guide will help you to get started. You may also want to sign up for our August 29 Webinar (“New Mobile Push Notifications from Amazon SNS”).

As always, this functionality is available now and you can start using it today in all public AWS Regions. I am really looking forward to hearing from you after you have migrated your existing application or built something new!

— Jeff;

Modified 2/11/2021 – In an effort to ensure a great experience, expired links in this post have been updated or removed from the original post.