I am creating an Expo app that will use push notifications. I do not want to use Expo's server for that and instead I want to use AWS SNS. This is what I have done:
When I try to send a push notification, it doesn't work. I tried:
I am thinking that if I am able to build the app and obtain the device token I may be able to make it work, but no luck. Any idea on what I am doing wrong or what I am supposed to be doing?
After 2 days of fighting to get this to work I finally did it. I am going to provide all the steps I followed in hopes that this can help other people:
"android": {
"googleServicesFile": "./google-services.json",
"package": "com.astest.mypackage",
"useNextNotificationsApi": true
},
Follow the instructions here on how to set up your client app. Make sure you do not include the sendPushNotification() function since you will actually be using SNS instead.
In the registerForPushNotificationsAsync() function make sure you use .getDevicePushTokenAsync() instead of .getExpoPushTokenAsync()
Create a platform application in SNS
In your code, make sure you create an application endpoint in SNS. Or do it through the console.
Test the set up by sending a test message using the console in SNS. Select your endpoint and then click on "Publish message".
Click on "custom payload for each delivery".
use this code:
{
"GCM": "{ \"notification\": {\"title\": \"Title of notification\", \"body\": \"It works\" } }"
}
Click on publish message.
To publish a message programmatically you can do:
var sns = new AWS.SNS({ apiVersion: '2010-03-31', region: 'us-east-1'})
let notification = JSON.stringify({
'notification': {
'title': "title of notification",
'body': "Your message goes here",
'data': {}
}
});
var params = {
Message: JSON.stringify({
GCM: notification
}),
MessageStructure: "json",
TargetArn: "###Your Target ARN##"
};
sns.publish(params, function(err, data) {
if (err) {
console.log("There was an error sending the push notification----> ", err)
} // an error occurred
else{
console.log("Push notification sent successfully!!!! ", data);
} // successful response
});
Now, this is only for Android of course. But it works! Adapting it to APN shouldn't be too difficult.
EDIT 1 If you want your Expo, managed flow, app to respond to the notification you are sending you need to make a couple of changes. I spent the last 3 days trying to figure this out and I finally did.
According to the Expo documentation there are 2 types of push notifications you can send, "notification" and "data". In the example I provided in the steps above I was using "notification". The problem with that is that Expo "is not made aware that the notification is being received" when you use notifications, which means you can't respond to notifications. Therefore, if you need to respond or parse the response received in the notification you need to use a push notification of type "data".
Therefore, in the code example I gave above you need to change the word "notification" for "data".
In addition to sending "data" push notification instead of just "notifications", you must include the "experienceId in your payload, which you can get from your app
Defaults to Constants.manifest.id exposed by expo-constants. In the bare workflow, you must provide a value which takes the shape @username/projectSlug, where username is the Expo account that the project is associated with, and projectSlug is your slug from app.json.
The other change you need to make is the part where the content of your push notification goes. In the code I gave above I included it in a property called "body". With the "data" type of notification it needs to be changed to "message"
Also, the part where you add your key-value pairs also need to change. In the example I gave above the propertyis called "data", but this time we need to change it to "body"
An this is the resulting code:
let dataNotification = JSON.stringify({
'data': {
'title': title,
'message': message,
'body': { your key-value-pairs},
'experienceId': "@yourExpoUsername/Your-Project-Slug"
}
});