Setting up Android Push Notifications with AWS Amplify
In this post, we set up a React Native app using AWS Amplify to receive Android Push Notifications. If you are interested in iOS Push Notifications, see Nader Dabit’s official post.
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 is based on the AWS Amplify Push Notification documentation. I found the process to require a lot of care, so I wrote this up to examine and detail some steps that I had issues with.
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
Create a new React Native project> npx react-native init AmplifyAndroidPush
Install the AWS Amplify libraries, explicitly including push notifications> npm install aws-amplify aws-amplify-react-native amazon-cognito-identity-js @aws-amplify/pushnotification
Initialize AWS Amplify in the project, using the default settings> amplify init
Google Firebase Setup
Go to the Google Firebase Console
Add a project
Enter the project’s name
Enable Google Analytics if you want to be able to see stats
Choose or create a Google Analytics account for the project
Continue to the Project Overview page
Add Firebase to your Android app
Enter the Android package name
Recall that your Android package name can be found in android/app/build.gradle
// android/app/build.gradle
android {
defaultConfig {
applicationId "com.amplifyandroidpush"
}
}
As instructed by Firebase console, download google-services.json
and place it in the android/app
directory
As instructed by Firebase console, add the latest version of com.google.gms:google-services
to android/build.gradle
// android/build.gradle
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.3'
}
}
As instructed by Firebase console, add the latest versions of com.google.firebase:firebase-messaging
and com.google.firebase:firebase-analytics
to android/app/build.gradle
// android/app/build.gradle
dependencies {
implementation 'com.google.firebase:firebase-messaging:20.1.0'
implementation 'com.google.firebase:firebase-analytics:17.2.1'
}
apply plugin: 'com.google.gms.google-services'
Note: The AWS Amplify Push Notification documentation shows the line
compile project(’:@aws-amplify/pushnotification’)
I believe that’s inserted by manually linking@aws-amplify/pushnotification
and won’t show up if you are using React Native post-0.60 auto-linking. Do not manually insert the compile line into the build.gradle file to match the documentation — if you do, you will get the following error:
* What went wrong:
A problem occurred evaluating project ':app'.
> Project with path ':@aws-amplify/pushnotification' could not be found in project ':app'.
Continue to return to the Project Overview page, then click the Gear icon, then Project Settings
In the Settings: Cloud Messaging tab, save the Project credentials: Server key. You will need this when you run amplify add notifications
later.
As instructed in the AWS Amplify Push Notification documentation, add the <!-- [START Push notification config -->
lines to android/app/src/main/AndroidManifest.xml
Since this step is exactly like the documentation, I won't replicate the lines here.
Setup AWS Amplify
Add authentication, using the default settings> amplify add auth
Note: If you don’t add authentication manually here, the next step (
amplify add notifications
) would add authentication implicitly, but it would only create an identity pool, not both a user pool and an identity pool like this step does.
Add push notifications, choose the FCM
(Firebase Cloud Messaging) push notification channel, and, when prompted for an ApiKey
, enter the Project credentials: Server key that you previously saved from the Google Firebase Console.
> amplify add notifications
? Choose the push notification channel to enable. FCM
An Amazon Pinpoint project will be created for notifications.
? Provide your pinpoint resource name: AmplifyAndroidPushXXXXX
√ Successfully created Pinpoint project: AmplifyAndroidPushXXXXX-env
√ Successfully set the IAM policy
Adding notifications would also add the Auth category to the project if not already added.
Successfully updated auth resource locally.
Execute "amplify push" to update the Auth resources in the cloud.
? ApiKey XXXXXXX
√ The FCM channel has been successfully enabled.
Note: Do NOT also run
amplify add analytics
becauseamplify add notifications
already initializes an AWS Pinpoint project, calledAmplifyAndroidPushXXXXX-env
Push your authentication setup into AWS (your analytics setup was already pushed during the amplify add notifications
step).> amplify push
Configure AWS Amplify in index.js
// index.js
import Amplify from 'aws-amplify';
import config from './aws-exports';
Amplify.configure(config);
Note: you do not have to separately run
PushNotification.configure
Configure push notification handler functions in App.js
// App.js
import PushNotification from '@aws-amplify/pushnotification';
PushNotification.onRegister(token => {
console.log('onRegister', token);
});
PushNotification.onNotification(notification => {
if (notification.foreground) {
console.log('onNotification foreground', notification);
} else {
console.log('onNotification background or closed',
notification);
}
// extract the data passed in the push notification
const data = JSON.parse(notification.data['pinpoint.jsonBody']);
console.log('onNotification data', data);
// iOS only
notification.finish(PushNotificationIOS.FetchResult.NoData);
});
PushNotification.onNotificationOpened(notification => {
console.log('onNotificationOpened', notification);
// extract the data passed in the push notification
const data = JSON.parse(notification['pinpoint.jsonBody']);
console.log('onNotificationOpened data', data);
});
Note: Place these components only at the top-level, not inside a React component. If you do place them inside a React component, like in an Effect hook, your
onNotification
andonNotificationOpened
handler functions will not be triggered if the app is closed (not running in foreground or background) when a push notification is received and clicked on.
PushNotification.onRegister
Your PushNotification.onRegister
handler function is supposed to be called by AWS Amplify the first time the FCM device token is fetched and cached. All future launches of the app should not trigger this handler function, as the FCM device token is already cached and does not need to be re-fetched.
Note: In my testing, I never noticed my
PushNotification.onRegister
handler function being called, even though the FCM device token was correctly fetched and cached by AWS Amplify. I didn’t find this configuration function that useful in practice (as opposed toPushNotification.onNotification
andPushNotification.onNotificationOpened
), so it didn’t matter much.Additional Note: I’ve seen Github comments that say that you have to write the following function to manually update the Pinpoint endpoint with the device token once it’s received:
PushNotification.onRegister(token => {
PushNotification.updateEndpoint(token);
});
I didn’t find this to be true. AWS Amplify will call
PushNotification.updateEndpoint
automatically ininitializeAndroid
andinitializeIOS
to update AWS Pinpoint with the FCM device token. No manual calls toPushNotification.updateEndpoint
should be necessary.
For information on the PushNotification.onNotification
and PushNotification.onNotificationOpened
configuration functions, see Handling Incoming Push Notifications in AWS Amplify.
Your initial setup is now complete.
To test your configuration, see Testing Push Notifications with AWS Amplify & CLI.
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