Firebase FCM push notifications not show on iOS 12 - django

I am using python 3 and Django framework with Firebase FCM to send push notifications from an iOS device. The push notifications did not show on device, until yesterday.
When I now send a push notification, everything shows successful, but nothing is received on the device.
If I send directly via a curl request, this is the response:
{'failure': 0, 'canonical_ids': 0, 'success': 1, 'multicast_ids': [8348728835412078810], 'topic_message_id': None, 'results': [{'message_id': '0:1543820637538874%6467bacd6467abcd'}]}
If I send from the Notification dashboard on the firebase console, it shows successfully completed.
I have done the following with no success:
Locked in pod for, 'Firebase/Core' and 'Firebase/Messaging'.
Generated a new APN key on developer console and replaced the
existing key on FCM setup in Firebase.
Downloaded a fresh GoogleService-Info.plist and replaced existing
Checked that bundle id's etc all match.
Updated firebase pods to latest versions
Turned message swizzling off in info.plist file (i.e. FirebaseAppDelegateProxyEnabled = No)
Setting Messaging.messaging().shouldEstablishDirectChannel = true
Made sure remote notification in Capabilities are still turned on

Related

Using SNS to send push notifications - Expo App

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:
Created the app in Firebase and obtained the API Key.
Created the platform application on SNS using the API key obtained in step 1.
Used expo to obtained the device token.
Created an endpoint on SNS in the application created in step 2.
When I try to send a push notification, it doesn't work. I tried:
I made sure that use .getDevicePushTokenAsync() instead of getExpoPushTokenAsync() to get the device token that can be used with SNS.
When I test the app on my Android device I am able to console.log the device token (which is what I use to add the endpoint mentioned in step 4 above. Still nothing :(
I built a stand alone app, downloaded the .apk file, installed it on my device, BUT NOW THE PUSH TOKEN IS NOT BEING RETRIEVED. I really do not know why after building the app and installing it on my device this doesn't work anymore. It returns
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:
Create a Firebase Project.
Click on "Add Project"
Provide a name. Click on "Continue"
Click on "Create Project"
Once the project is ready, click on "Continue"
Click on the gear icon right next to where it says "Project Overview"
Click on Project Settings.
In the page that shows up click on Cloud Messaging
Copy the value for "Server key". You will use it later when creating an application platform in SNS.
In that same "settings" page click on the "General" tab.
At the bottom of the page you are going to see a section that says "Your Apps". It should say: "There are no apps in your project". Click on the icon for Android.
This is an important step. You need to provide the "Android package name". Go to your Expo app and find the value for android.package. Copy it and put it where it asks for the Android package name on Firebase.
Click on "Register App".
Important step. Click on the button that says "Download google-services.json".
Save the file AT THE ROOT OF YOUR EXPO PROJECT.
Go back to your app.json file in your Expo project. Where it has the android value make sure this is what you have at least:
"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
Push notification platform: Choose FCM
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"
}
});

AWS Pinpoint error after updating APNS certificate with Expo

After sending a new build to the app store, the push notifications for my app are no longer working. During the build, expo made a new APNS certificate, and now when I try to push a notification to users, I get the following error message.
"'{"errorMessage":"Invalid
Credentials","channelType":"APNS","pushProviderStatusCode":"403","pushProviderError":"InvalidProviderToken","pushProviderResponse":"{\"reason\":\"InvalidProviderToken\"}"}'"
I get the same error message when attempting to send myself a notification through the AWS Console. I tried to update my push notification credentials on expo, but get a similar error:
? Path to P8 file: /Users/REDACTED/Downloads/AuthKey_D3QREDACTED-1.p8
? Key ID: REDACTED ? Apple Team ID: REDACTED Unable to validate Push
Keys due to insufficient Apple Credentials
I tried following every thread I could find online about the error and verified that I had the right Team ID and Key ID, but it still does not work.
Happy to provide more info if needed, and thank you for your help
I just had to regenerate a new .p8 file and upload it to AWS pinpoint
I had this issue recently, and no matter how many times I tired to "Edit" the APNs configuration it would not work. Eventually I just removed APNs setting from PinPoint, saved it, and then set it up again fresh.
Now it works.

Sending notification to GCM from Django via FCM token

I am doing my first steps in Django-Android interaction, and I am bit confused about the logic how FCM technology works. I have installed django-fcm via pip, and now my goal is to send a notification to Android device via FCM token that has been sent to server by Android device via REST resource.
The third-party Android developers tell that they would give me only the FCM token and I should be able to send a notification. And I'm a bit confused by the following code snippet from the doc
devices = FCMDevice.objects.all()
What is FCM device ? And how does JSON code in the example:
{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "myicon"
}
}
...related to this:
device = FCMDevice.objects.all().first()
device.send_message("Title", "Message")
device.send_message(data={"test": "test"})
device.send_message(title="Title", body="Message", icon=..., data={"test": "test"})
THE QUESTION IS what is the minimum code snippet to send the simplest notification to an Android device identified by its FCM token
To send a notification via your django app server, you need to:
Install django-fcm and add 'fcm_django' to your INSTALLED_APPS.
Run migrations so as to have a device relation ready
in your database.
Assuming you already can send notifications from the Firebase
console, go to your Firebase console settings. On the Cloud
Messaging tab, copy the Server Key. Save this key in your django
configuration settings as FCM_APIKEY = <your_api_key>
Go to your android device and retrieve the Token, the docs for this
are at
https://firebase.google.com/docs/cloud-messaging/android/client
Now create a Device instance in django, use the retrieved token as
the reg_id.
To send a notification, you can send a notification using
device_instance.send_message
(notification = { "body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "myicon"})
To fully understand how django-fcm works, I would advice that you actually go through the source code. If an open source package is disturbing me, actually viewing the source code and reading the comments is sometimes enlightening. django-fcm is a small and simple package. The utils.py file is the most important. That is where the message is composed and sent to Firebase using the python's requests package. To understand this file. Please also read the docs for firebase at: https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json
First of all, FCMDevice is a django model object which contains the data about a registered device, to which notifications can be sent.
It is expected, that you provide that data. When you mobile device/browser gets that data from its FCM token from fcm library, it is expected that you register that token within your backend that uses the fcm-django library.
Meaning, you create an object within your database with using the model FCMDevice from the library.
Minimal code required to send the notification is exactly that, which you have posted in this post.
I believe you should perhaps read some django tutorials, to better understand what models actually are.

Amazon SNS: "Platform credentials are invalid" when re-entering a GCM API key that previously worked

We have been using Amazon SNS to send Android push notifications since April this year.
Pushes have sent with no problem, however there has never been any record of calls to the Cloud Messaging API in the Cloud Console (seems odd?).
Today I created a new API key for the Static Map service (unrelated) and renamed our Cloud Messaging API key (only the name, the key is the same). From this point no pushes have been sent, and trying to create a new platform application (or update the existing one) in AWS results in:
Invalid parameter: Attributes Reason: Platform credentials are invalid (Service: AmazonSNS; Status Code: 400; Error Code: InvalidParameter; Request ID:)
I have also tried manually making calls to the https://gcm-http.googleapis.com/gcm/send endpoint using the key which results in Unauthorized (401).
Interestingly, I can make calls to the above endpoint using the key I created today, however they fail on MismatchSenderId.
I can't see a lot of the previous options that the Cloud Console had (server / browser keys, etc) within the API Manager?
For those who are facing this in 2017, here goes a tip:
1 - Go to your firebase console (https://console.firebase.google.com/) click on your project (which you want to use for push notifications)
2 - Click on the "three dots" on the right side of your project name and click on "Settings"
3 - Click on "CLOUD MESSAGING" on the header tabs
4 - Copy the "Server Key" (this one is bigger than your API key)
5 - Paste on the "API Key" input of the AWS Form for "Create platform application"
PS: Note that this is valid only for GCM Push Notifications.
API Key management for GCM has been moved to Firebase Console.
You can create a new Firebase Project (or import an existing cloud project) and you should obtain a new Server Key for Cloud Messaging.
see the updated documentation:
https://developers.google.com/cloud-messaging/android/client#create-an-api-project
and the stack overflow question: Where can I find the API KEY for Firebase Cloud Messaging?
if you still have problems please contact:
https://firebase.google.com/support/contact/troubleshooting
I have been getting the same error when creating Amazon SNS platform application:
Invalid parameter: Attributes Reason: Platform credentials are invalid (Service: AmazonSNS; Status Code: 400; Error Code: InvalidParameter; Request ID:)
After reaching out to the Firebase support as suggested by Diego, this is the response I got from Google:
Hope you're doing well and thanks for reaching out to us.
I'm not really familiar with Amazon SNS and looks like their integration is still with GCM, not FCM. If your app implementation is still GCM, then you need to migrate with FCM in order to use the server key in the console. See the instructions here.
Also, Firebase has upgraded the server keys to a new version. We'd recommend to use the server key instead of the legacy server key.
I hope this helps. Let me know if you have any other concerns. Thank you.
This indicates that we'll have to change our app code. We were able to make this work for another app in out organization by creating a new firebase project and using the Legacy server key with Amazon SNS.
At some point we'll definitely upgrade to using FCM but at the moment we have a tight deadline.
Update:
So finally what worked for us is using the 'Server Key' under Project Settings --> Cloud Messaging . The app still uses the GCM implementation. Amazon SNS is happy with this key and generated a GCM platform push application. The pushes work !
Still confused about why the 'Legacy Server Key' does not work for one app but is ok for the other. But I am not digging into it any further.
For those starting a new project and wondering why it is still invalid, make sure the application Key restriction is set to Android apps. In my case, it was at only set to None and when I switched to Android apps, it worked after 5 to 10min after updating it. You'll need to add your package name and SHA-1 certificate fingerprint.

Confusion migrating Parse push to AWS SNS

I am a little confused about this migration path, as described in a recent aws blog post, and its aftermath:
It seems like quite a bit of trouble to have to rely on all my users to update in a timely fashion so that GCMSenderIDs can be attached to my existing parse data along with modified/valid device tokens.
Also, what happens to new installations after the migration is complete? In the guide it says no changes need to be made to client side code, but doesn't this require that the SNS sdk is installed so that new installations can be added to the client list?
Considering all this, wouldn't it make a lot more sense to simply forget about the old parse data and just push a client/app update that works solely with SNS and reregister all the devices that way? Why go through all the trouble to integrate with Parse when we are getting rid of it anyways?
AllTheTime,
Your existing Android user push tokens on Parse.com will no longer be valid after January 28, 2017 as Parse owns the API Server Key associated with the Sender ID that was granted the token. If you wish to reach those existing users via Push Notifications after January, you must update the existing Parse.com client app with your own Sender ID and have the app generate a new registration Id (token) associated with your Sender ID. There is no other way for you to convert the existing tokens over to SNS or any another 3rd party.
The SNS SDK is not required for the migration but it would make sense to integrate the SNS SDK when you update the app to retrieve new tokens using your Sender ID. At the time of token registration, the app can update the Parse.com database with the newly issued token AND also create a new Platform Endpoint with SNS.
As for post Parse Push migration and handling the new app installations, my suggestion is to build an after-save “webhook” on the _Installation class on Parse.com. The “webhook” would trigger any http endpoint when a row is created or updated in the _Installation class. The hook could trigger an API Gateway http endpoint that takes the newly generated or updated token and creates a new SNS platform endpoint. At this point, if you haven’t fully migrated from Parse.com, you can either publish to those tokens via Parse.com or SNS. By the time Jan 28, 2017 rolls around, nearly all your existing users would have launched the updated app and generated a new token or they no longer use your app.
Starting over with just SNS is another option but if you need to reach any of the users who have not updated the app then you would need to continue sending push notifications through Parse.com for those legacy users who have not updated the app AND you would then continue to send push notifications via SNS to those new app installs.
I hope this clarifies the migration for you.
Check out my other SO post regarding the Parse.com GCM Sender ID:
How to migrate off Parse to different SENDER_ID
-Dennis