AWS Mobile
Developer Guide

Add Push Notifications to Your Mobile App with Amazon Pinpoint

Overview

Android - JavaAndroid - KotliniOS - Swift
Android - Java

Enable your users to receive mobile push messages sent from the Apple (APNs) and Google (FCM/GCM) platforms. The CLI deploys a push notification backend using Amazon Pinpoint. You can also create Amazon Pinpoint campaigns that tie user behavior to push or other forms of messaging.

Android - Kotlin

Enable your users to receive mobile push messages sent from the Apple (APNs) and Google (FCM/GCM) platforms. The CLI deploys a push notification backend using Amazon Pinpoint. You can also create Amazon Pinpoint campaigns that tie user behavior to push or other forms of messaging.

iOS - Swift

Enable your users to receive mobile push messages sent from the Apple (APNs) and Google (FCM/GCM) platforms. The CLI deploys your push notification backend using Amazon Pinpoint. You can also create Amazon Pinpoint campaigns that tie user behavior to push or other forms of messaging.

Set Up Your Backend

  1. Complete the Get Started steps before you proceed.

  2. Use the CLI to add storage to your cloud-enabled backend and app.

    Android - JavaAndroid - KotliniOS - Swift
    Android - Java

    In a terminal window, navigate to your project folder (the folder that typically contains your project level build.gradle), and add the SDK to your app.

    $ cd ./YOUR_PROJECT_FOLDER $ amplify add notifications
    Android - Kotlin

    In a terminal window, navigate to your project folder (the folder that typically contains your project level build.gradle), and add the SDK to your app.

    $ cd ./YOUR_PROJECT_FOLDER $ amplify add notifications
    iOS - Swift

    In a terminal window, navigate to your project folder (the folder that typically contains your project level xcodeproj file), and add the SDK to your app.

    $ cd ./YOUR_PROJECT_FOLDER $ amplify add notifications
  3. Set up your backend to support receiving push notifications:

    Android - JavaAndroid - KotliniOS - Swift
    Android - Java
    • Choose Firebase Cloud Messaging (FCM).

      > FCM
    • Provide your ApiKey. The FCM console refers to this value as ServerKey. For information on getting an FCM ApiKey, see Setting Up Android Push Notifications

    Android - Kotlin
    • Choose Firebase Cloud Messaging (FCM).

      > FCM
    • Provide your ApiKey. The FCM console refers to this value as "ServerKey". For information on getting an FCM ApiKey, see Setting Up Android Push Notifications

    iOS - Swift
    • Choose Apple Push Notification Service (APNs).

      > APNS
    • Choose Certificate as your authentication method.

      > Certificate
    • Provide the path to your P12 certificate. For information on creating your APNs certificate, see Setting Up iOS Push Notifications.

    Use the steps in the next section to connect your app to your backend.

Connect to Your Backend

Use the following steps to connect add push notification backend services to your app.

Android - JavaAndroid - KotliniOS - Swift
Android - Java
  1. Set up AWS Mobile SDK components as follows.

    1. Add the following dependencies and plugin to your app/build.gradle:

      dependencies { // Overrides an auth dependency to ensure correct behavior implementation 'com.google.android.gms:play-services-auth:15.0.1' implementation 'com.google.firebase:firebase-core:16.0.1' implementation 'com.google.firebase:firebase-messaging:17.3.0' implementation 'com.amazonaws:aws-android-sdk-pinpoint:2.7.+' implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.7.+@aar') { transitive = true } } apply plugin: 'com.google.gms.google-services'
    2. Add the following to your project level build.gradle. Make sure that you specify the google repository:

      buildscript { dependencies { classpath 'com.google.gms:google-services:4.0.1' } } allprojects { repositories { google() } }
    3. AndroidManifest.xml must contain the definition of the following service for PushListenerService in the application tag:

      <service android:name=".PushListenerService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service>
  2. Create an Amazon Pinpoint client in the location of your push notification code.

    import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.Log; import com.amazonaws.mobile.client.AWSMobileClient; import com.amazonaws.mobile.client.AWSStartupHandler; import com.amazonaws.mobile.client.AWSStartupResult; import com.amazonaws.mobileconnectors.pinpoint.PinpointConfiguration; import com.amazonaws.mobileconnectors.pinpoint.PinpointManager; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.InstanceIdResult; public class MainActivity extends AppCompatActivity { public static final String TAG = MainActivity.class.getSimpleName(); private static PinpointManager pinpointManager; public static PinpointManager getPinpointManager(final Context applicationContext) { if (pinpointManager == null) { PinpointConfiguration pinpointConfig = new PinpointConfiguration( applicationContext, AWSMobileClient.getInstance().getCredentialsProvider(), AWSMobileClient.getInstance().getConfiguration()); pinpointManager = new PinpointManager(pinpointConfig); FirebaseInstanceId.getInstance().getInstanceId() .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() { @Override public void onComplete(@NonNull Task<InstanceIdResult> task) { final String token = task.getResult().getToken(); Log.d(TAG, "Registering push notifications token: " + token); pinpointManager.getNotificationClient().registerDeviceToken(token); } }); } return pinpointManager; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize the AWS Mobile Client AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() { @Override public void onComplete(AWSStartupResult awsStartupResult) { Log.d(TAG, "AWSMobileClient is instantiated and you are connected to AWS!"); } }).execute(); // Initialize PinpointManager getPinpointManager(getApplicationContext()); } }
Android - Kotlin
  1. Set up AWS Mobile SDK components as follows.

    1. Add the following dependencies and plugin to your app/build.gradle:

      dependencies { // Overrides an auth dependency to ensure correct behavior implementation 'com.google.android.gms:play-services-auth:15.0.1' implementation 'com.google.firebase:firebase-core:16.0.1' implementation 'com.google.firebase:firebase-messaging:17.3.0' implementation 'com.amazonaws:aws-android-sdk-pinpoint:2.7.+' implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.7.+@aar') { transitive = true } } apply plugin: 'com.google.gms.google-services'
    2. Add the following to your project level build.gradle. Make sure that you specify the google repository:

      buildscript { dependencies { classpath 'com.google.gms:google-services:4.0.1' } } allprojects { repositories { google() } }
    3. AndroidManifest.xml must contain the definition of the following service for PushListenerService in the application tag:

      <service android:name=".PushListenerService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service>
  2. Create an Amazon Pinpoint client in the location of your push notification code.

    import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.support.v4.content.LocalBroadcastManager import android.support.v7.app.AlertDialog import android.util.Log import com.amazonaws.mobile.client.AWSMobileClient import com.amazonaws.mobileconnectors.pinpoint.PinpointConfiguration import com.amazonaws.mobileconnectors.pinpoint.PinpointManager import com.google.firebase.iid.FirebaseInstanceId class MainActivity : AppCompatActivity() { private val notificationReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Log.d(TAG, "Received notification from local broadcast. Display it in a dialog.") val bundle = intent.extras val message = PushListenerService.getMessage(bundle!!) AlertDialog.Builder(this@MainActivity) .setTitle("Push notification") .setMessage(message) .setPositiveButton(android.R.string.ok, null) .show() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Initialize the AWS Mobile Client AWSMobileClient.getInstance().initialize(this) { Log.d(TAG, "AWSMobileClient is instantiated and you are connected to AWS!") }.execute() // Initialize PinpointManager getPinpointManager(applicationContext) } override fun onPause() { super.onPause() // Unregister notification receiver LocalBroadcastManager.getInstance(this).unregisterReceiver(notificationReceiver) } override fun onResume() { super.onResume() // Register notification receiver LocalBroadcastManager.getInstance(this).registerReceiver(notificationReceiver, IntentFilter(PushListenerService.ACTION_PUSH_NOTIFICATION)) } companion object { val TAG = MainActivity.javaClass.simpleName private var pinpointManager: PinpointManager? = null fun getPinpointManager(applicationContext: Context): PinpointManager? { if (pinpointManager == null) { val pinpointConfig = PinpointConfiguration( applicationContext, AWSMobileClient.getInstance().credentialsProvider, AWSMobileClient.getInstance().configuration) pinpointManager = PinpointManager(pinpointConfig) FirebaseInstanceId.getInstance().instanceId .addOnCompleteListener { task -> val token = task.result.token Log.d(TAG, "Registering push notifications token: $token") pinpointManager!!.notificationClient.registerDeviceToken(token) } } return pinpointManager } } }
iOS - Swift
  1. Set up AWS Mobile SDK components with the following Step 2: Set Up Your Backend steps.

    1. Podfile that you configure to install the AWS Mobile SDK must contain:

      platform :ios, '9.0' target :'YOUR-APP-NAME' do use_frameworks! pod 'AWSPinpoint', '~> 2.6.13' # other pods end

      Run pod install --repo-update before you continue.

      If you encounter an error message that begins "[!] Failed to connect to GitHub to update the CocoaPods/Specs . . .", and your internet connectivity is working, you may need to update openssl and Ruby.

    2. Classes that call Amazon Pinpoint APIs must use the following import statements:

      import AWSCore import AWSPinpoint
  2. Create an Amazon Pinpoint client by using the following code into the didFinishLaunchwithOptions method of your app's AppDelegate.swift. This will also register your device token with Amazon Pinpoint.

    Note: If you have already integrated Analytics, you can skip this step.

    /** start code copy **/ var pinpoint: AWSPinpoint? /** end code copy **/ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { /** start code copy **/ pinpoint = AWSPinpoint(configuration: AWSPinpointConfiguration.defaultPinpointConfiguration(launchOptions: launchOptions)) /** end code copy **/ return true }

Add Amazon Pinpoint Targeted and Campaign Push Messaging

The Amazon Pinpoint console enables you to target your app users with push messaging. You can send individual messages or configure campaigns that target a group of users that match a profile that you define. For instance, you could email users that have not used the app in 30 days, or send an SMS to those that frequently use a given feature of your app.

Android - JavaAndroid - KotliniOS - Swift
Android - Java

The following steps show how to receive push notifications targeted for your app.

  1. Add a push listener service to your app.

    The name of the class must match the push listener service name used in the app manifest. pinpointManager is a reference to the static PinpointManager variable declared in the MainActivity shown in a previous step. Use the following steps to detect and display Push Notification in your app.

    1. The following push listener code assumes that the app's MainActivity is configured using the manifest setup described in a previous section.

      import android.content.Intent; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import com.amazonaws.mobileconnectors.pinpoint.targeting.notification.NotificationClient; import com.amazonaws.mobileconnectors.pinpoint.targeting.notification.NotificationDetails; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; import java.util.HashMap; public class PushListenerService extends FirebaseMessagingService { public static final String TAG = PushListenerService.class.getSimpleName(); // Intent action used in local broadcast public static final String ACTION_PUSH_NOTIFICATION = "push-notification"; // Intent keys public static final String INTENT_SNS_NOTIFICATION_FROM = "from"; public static final String INTENT_SNS_NOTIFICATION_DATA = "data"; @Override public void onNewToken(String token) { super.onNewToken(token); Log.d(TAG, "Registering push notifications token: " + token); MainActivity.getPinpointManager(getApplicationContext()).getNotificationClient().registerDeviceToken(token); } @Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); Log.d(TAG, "Message: " + remoteMessage.getData()); final NotificationClient notificationClient = MainActivity.getPinpointManager(getApplicationContext()).getNotificationClient(); final NotificationDetails notificationDetails = NotificationDetails.builder() .from(remoteMessage.getFrom()) .mapData(remoteMessage.getData()) .intentAction(NotificationClient.FCM_INTENT_ACTION) .build(); NotificationClient.CampaignPushResult pushResult = notificationClient.handleCampaignPush(notificationDetails); if (!NotificationClient.CampaignPushResult.NOT_HANDLED.equals(pushResult)) { /** The push message was due to a Pinpoint campaign. If the app was in the background, a local notification was added in the notification center. If the app was in the foreground, an event was recorded indicating the app was in the foreground, for the demo, we will broadcast the notification to let the main activity display it in a dialog. */ if (NotificationClient.CampaignPushResult.APP_IN_FOREGROUND.equals(pushResult)) { /* Create a message that will display the raw data of the campaign push in a dialog. */ final HashMap<String, String> dataMap = new HashMap<>(remoteMessage.getData()); broadcast(remoteMessage.getFrom(), dataMap); } return; } } private void broadcast(final String from, final HashMap<String, String> dataMap) { Intent intent = new Intent(ACTION_PUSH_NOTIFICATION); intent.putExtra(INTENT_SNS_NOTIFICATION_FROM, from); intent.putExtra(INTENT_SNS_NOTIFICATION_DATA, dataMap); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } /** * Helper method to extract push message from bundle. * * @param data bundle * @return message string from push notification */ public static String getMessage(Bundle data) { return ((HashMap) data.get("data")).toString(); } }
Android - Kotlin

The following steps show how to receive push notifications targeted for your app.

  1. Add a push listener service to your app.

    The name of the class must match the push listener service name used in the app manifest. pinpointManager is a reference to the static PinpointManager variable declared in the MainActivity shown in a previous step. Use the following steps to set up Push Notification listening in your app.

    1. The following push listener code assumes that the app's MainActivity is configured using the manifest setup described in a previous section.

      import android.content.Intent import android.os.Bundle import android.support.v4.content.LocalBroadcastManager import android.util.Log import com.amazonaws.mobileconnectors.pinpoint.targeting.notification.NotificationClient import com.amazonaws.mobileconnectors.pinpoint.targeting.notification.NotificationDetails import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import java.util.HashMap class PushListenerService : FirebaseMessagingService() { override fun onNewToken(token: String?) { super.onNewToken(token) Log.d(TAG,"Registering push notifications token: " + token!!) MainActivity.getPinpointManager(applicationContext)?.notificationClient?.registerDeviceToken(token) } override fun onMessageReceived(remoteMessage: RemoteMessage?) { super.onMessageReceived(remoteMessage) Log.d(TAG,"Message: " + remoteMessage?.data) val notificationClient = MainActivity.getPinpointManager(applicationContext)?.notificationClient val notificationDetails = NotificationDetails.builder() .from(remoteMessage?.from) .mapData(remoteMessage?.data) .intentAction(NotificationClient.FCM_INTENT_ACTION) .build() val pushResult = notificationClient?.handleCampaignPush(notificationDetails) if (NotificationClient.CampaignPushResult.NOT_HANDLED != pushResult) { /** * The push message was due to a Pinpoint campaign. * If the app was in the background, a local notification was added * in the notification center. If the app was in the foreground, an * event was recorded indicating the app was in the foreground, * for the demo, we will broadcast the notification to let the main * activity display it in a dialog. */ if (NotificationClient.CampaignPushResult.APP_IN_FOREGROUND == pushResult) { /* Create a message that will display the raw data of the campaign push in a dialog. */ val dataMap = HashMap(remoteMessage?.data) broadcast(remoteMessage?.from, dataMap) } return } } private fun broadcast(from: String?, dataMap: HashMap<String, String>) { val intent = Intent(ACTION_PUSH_NOTIFICATION) intent.putExtra(INTENT_SNS_NOTIFICATION_FROM, from) intent.putExtra(INTENT_SNS_NOTIFICATION_DATA, dataMap) LocalBroadcastManager.getInstance(this).sendBroadcast(intent) } companion object { val TAG = PushListenerService.javaClass.simpleName // Intent action used in local broadcast val ACTION_PUSH_NOTIFICATION = "push-notification" // Intent keys val INTENT_SNS_NOTIFICATION_FROM = "from" val INTENT_SNS_NOTIFICATION_DATA = "data" /** * Helper method to extract push message from bundle. * * @param data bundle * @return message string from push notification */ fun getMessage(data: Bundle): String { return (data.get("data") as HashMap<*, *>).toString() } } }
iOS - Swift
  1. In your AppDelegate with PinpointManager instantiated, make sure the push listening code exists in the following functions.

    // . . . other app delegate methods func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { pinpoint!.notificationManager.interceptDidRegisterForRemoteNotifications( withDeviceToken: deviceToken) } func application( _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { pinpoint!.notificationManager.interceptDidReceiveRemoteNotification( userInfo, fetchCompletionHandler: completionHandler) if (application.applicationState == .active) { let alert = UIAlertController(title: "Notification Received", message: userInfo.description, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) UIApplication.shared.keyWindow?.rootViewController?.present( alert, animated: true, completion:nil) } } // . . . other app delegate methods }

    Note

    If you already have push notification delegate methods, you can just add the interceptDidRegisterForRemoteNotifications and interceptDidReceiveRemoteNotification callbacks to Pinpoint client.

  2. Add the following code in the ViewController where you want to request notification permissions. Adding this code will prompt the end user to give permissions for receiving push notifications.

    var userNotificationTypes : UIUserNotificationType userNotificationTypes = [.alert , .badge , .sound] let notificationSettings = UIUserNotificationSettings.init(types: userNotificationTypes, categories: nil) UIApplication.shared.registerUserNotificationSettings(notificationSettings) UIApplication.shared.registerForRemoteNotifications()
  3. In Xcode Project Navigator, choose your app name at the top, choose your app name under Targets, choose the Capabilities tab, and then turn on Push Notifications.

    
                           Image of turning on Push Notifications capabilities in Xcode.
  4. Configure the app to run in the Release profile instead of the default Debug profile. Perform the following steps to get a notification to the device:

    1. For your app target, go to the General tab of project configuration and make sure Automatically Manage Signing check box is not selected.

    2. In the Signing(Release) section, choose the production provisioning profile you created on Apple developer console. For testing push notifications on a device, you will need an Ad Hoc Provisioining Profile configured with a Production AppStore and Ad Hoc certificate, and with the device(s) to be used for testing.

    3. In the top left corner of Xcode (where your app name is displayed next to the current build target device), choose on your app name and then select Edit Scheme, and then set Build configuration to Release

      Run your app on an iPhone device to test. Push notifications are not supported on simulators.

    4. Xcode will give an error that it could not run the app, this is due to production profile apps not being allowed to debug. Click Ok and launch the app directly from the device.

    5. When prompted, chose to allow notifications for the device.

    6. To create a new campaign to send notifications to your app from the Amazon Pinpoint console run the following command from your app project folder.

      $ cd YOUR_APP_PROJECT_FOLDER $ amplify notifications console
    7. Provide a campaign name, choose Next, choose Filter by standard attributes, and then choose iOS as the platform.

    8. You should see 1 device as a targeted endpoint, which is the app we are running on the iPhone device. Choose the option and then choose Next Step.

    9. Provide text for a sample title and body for push notification, and then choose Next Step.

    10. Choose Immediate, and then choose Next Step.

    11. Review the details on the screen, and then choose Launch Campaign.

    12. A notification should appear on the iPhone device. You may want to try testing your app receiving notifications when it is in the foreground and when closed.