GCM data not being passed by AWS SNS - android

I'm using Amazon SNS to send push notifications to an Android device. If I send the following JSON I can't read the parameters in the data element.
{
"default": "message here",
"GCM": {
"data": {
"message": "This is the message"
}
}
}
I can read the default element but in my broadcastreceiver I can't do this.
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
Log.d("GCM",extras.getString("message");
}
Trying to read the message element causes an error.
If I send directly through GCM I can read all of the parameters that start with data. using the above method with no problem at all.
What am I doing wrong?

You need escape double quotation in GCM value.
{ "default": "message here", "GCM": "{ \"data\": { \"message\": \"This is the message\" } }" }

Related

Sending data from api to my app via firebase cloud messaging

i have an app where i get certain data like date , time , team 1 and team 2 from sport api , i want to use FCM to show a notification with data every time ( my notifications are for football live games of premier league , so when games start playing , a notification should pop up in the user app ), is it possible to send data from api to my app via FCM to show a notification , i ve read a little bit about FCM HTTP V1 , but i'm still not sure wether it does the job or not , any suggestions guys , thank you .
You can send JSON that target a specific Topic to all user that subscribe to that Topic.
You can subscribe the user in the that topic by calling this
FirebaseMessaging.getInstance().subscribeToTopic("your_topic");
Once subscribe you can send this JSON to the API https://fcm.googleapis.com/fcm/send
{
"to":"/topics/your_topic",
"notification": {
"title": "Title Message"
"body": "Body Message"
},
"data": {
"time": "your time"
"date": "your date"
"home_team": "your home team"
"away_team": "your away team"
}
together with your headers "Content-Type", "application/json" and "Authorization", "key=your_FCM_legacy_server_key"
it's up to you on how you handle that "data" on your NotificationService
this how you handle the data in this part of JSON
"data": {
"time": "your time"
"date": "your date"
"home_team": "your home team"
"away_team": "your away team"
}
handle it like this
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Map<String, String> data = remoteMessage.getData();
String time= data.get("time");
String date= data.get("date");
String home_team= data.get("home_team");
String home_away= data.get("home_away");
String body = remoteMessage.getNotification().getBody(); //retrieve the notification body
String title = remoteMessage.getNotification().getTitle(); //retrieve the notification title
}

PubNub Push Notification sends incorrect data on Android

Let me go straight to the point, with Firebase Cloud Messaging and Android Oreo there have been some major changes when it comes to using their APIs.
I have entered my Firebase Server Api Key in the PubNub Console, push notification works absolutely fine on the Firebase console, but when publishing notification with PubNub, remoteMessage.toString gives => com.google.firebase.messaging.RemoteMessage#ffe9xxx in the OnMessageReceived function.
I am publishing something like this
JsonObject payload = new JsonObject();
JsonObject androidData = new JsonObject();
androidData.addProperty("contentText","test content");
androidData.addProperty("contentTitle","Title");
JsonObject notification = new JsonObject();
notification.add("notification",androidData);
JsonObject data = new JsonObject();
data.add("data", notification);
payload.add("pn_gcm", data);
in
PubNubObject.publish()
.message(payload)
etc..
Any idea why is this happening?
Thank you in advance.
Code on the receiving end
There is a class which extends FirebaseMessagingService, codes for OnMessageReceived function:
if (remoteMessage.getNotification() != null) {
//for testing firebase notification
Log.d(TAG, "Message Notification
Body:"+remoteMessage.getNotification().getBody());
} else {
//for anything else, I wanted to see what was coming from the server
//this is where I am getting the message when using PubNub notification
Log.d(TAG, "onMessageReceived: remoteMessage to
str:"+remoteMessage.toString() );
}
Android getData vs getNotification API
You are nesting the notification key/value inside of the data key and just need to use the API, remoteMessage.getData() instead of remoteMessage.getNotification().
If notification key was at the top level, it would work. See Android docs here.
Instead of this:
{
"pn_gcm": {
"data": {
"notification": {
"contentText": "test content",
"contentTitle": "Title"
}
}
}
}
This if switing to remoteMessage.getData():
{
"pn_gcm": {
"data": {
"contentText": "test content",
"contentTitle": "Title"
}
}
}
Or this if sticking with remoteMessage.getNotification():
{
"pn_gcm": {
"notification": {
"contentText": "test content",
"contentTitle": "Title"
}
}
}
}
PubNub basically just looks for the pn_gcm in the message payload when it is published and grabs whatever is inside of it and passes that directly to Google's FCM service for the devices that are registered (with PubNub) for that channel to receive GCM (FCM).
If the data is not formatted properly we would receive an error back from FCM which should be reported on the channel's -pndebug channel (assuming pn_debug:true was included in the published message payload).
For full details on troubleshooting FCM (GCM) or APONS issues with PubNub, please review How can I troubleshoot my push notification issues?

How to get value from FCM data message in Android?

I'm trying to implement FCM notification in my app. I have read FCM data message type will receive notification even when app is in background so am trying to implementing that in onMessageRecieved method am getting unexpected response like this:
{title =2, message={"Status":"UNASSIGNED","CompanyName":"gd","LastModifiedDateTime":"2017-04-25 18:59:41","IsPartRequired":false,"ProblemCategory":"CONFIGURATION","IsGeneralClaim":false,"RegistrationID":1057,"IncidentCode":"INS\/2017\/04\/25-0010","StatusID":0,"CreatedDateTime":"2017-04-25 18:59:41","IsInstallationCall":false}}
Don't know how to parse this get separate value from title and message let me post my firebase message code:
public class FireBaseMessage extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Map<String,String> data = remoteMessage.getData();
Log.d(TAG, "From: " + data.toString());
//
}
}
In this log message am getting response like that how to get value from that is try like:
int title=data.get("title");
getting null pointer as this is not in valid format. In my server side i have am trying to post json format like this:
{
"to":"es_OToDkj00:APA91bFqxbVMAaXy5fPtDbNVAkIwyVrPCmfGci2otHZPvdRoXPv-oDdjgtLR92Nqe8w6f57nCVceLbc3_zBWsInG9g1Pfdp3LvsMKyuaiYps0L1y3tn0N0XbzGseEI6jyiqs1r-sT9lb",
"data":{
"message":{
"RegistrationID":1057,
"IncidentCode":"INS/2017/04/25-0010",
"CompanyName":"ABM INFOTECH",
"StatusID":5,
"Status":"ASSIGNED",
"CreatedDateTime":"2017-04-25T12:03:45",
"LastModifiedDateTime":"2017-04-25T18:59:41",
"ProblemCategory":"CONFIGURATION",
"IsPartRequired":false,
"IsInstallationCall":false,
"IsGeneralClaim":false
},
"title ":"1"
}
Don't know where I'm making a mistake. Can anyone help me? Thanks in advance!
To get the Title: from message payload
use:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
//In case when notification was send in "notification" parameter we need to check wheather data is null or not.
if (remoteMessage.getData()!=null && remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
String title = remoteMessage.getData().get("title").toString();
}
}
EDIT
check if your remoteMessage contain the specific key:
if (remoteMessage.getData()!=null){
for (Map.Entry<String, String> entry : remoteMessage.getData().entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
Log.d(TAG, "key, " + key + " value " + value);
}}
There are two types of FCM messages:
1) Notification Messages
2) Data Messages
Notification Message Structure:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
}
In order to get data from the notification payload/messages:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message From " + remoteMessage.getFrom()); //sender ID
Log.d(TAG, "Notification Title " + remoteMessage.getNotification().getTitle()); //notification title
Log.d(TAG, "Notification Body " + remoteMessage.getNotification().getBody()); //notification body
}
}
Data Message Structure:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}
}
In order to get data from the data payload/messages:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Data: " + remoteMessage.getData()); //Whole data
Log.d(TAG, "Key Data : " + remoteMessage.getData().get("key").toString()); //Get specific key data
}
}
You have an extra space character in your "title" parameter:
"title ":"1"
It's hard to see since it's just a space. It should be:
"title":"1"
The reason you're note getting any value is because technically, the key being sent is "title " (with a space), while in your client code, you're only using "title" (without a space).
You should be able to receive it correctly after you remove the extra space.
After many search I have found this answer, it working perfect
To make firebase library to call your onMessageReceived() in the following cases
App in foreground
App in background
App has been killed
you must not put JSON key 'notification' in your request to firebase API but instead use 'data', see below.
The following message will not call your onMessageReceived() when your app is in the background or killed, and you can't customize your notification.
{
"to": "/topics/journal",
"notification": {
"title" : "title",
"text": "data!",
"icon": "ic_notification"
}
}
but instead using this will work
{
"to": "/topics/dev_journal",
"data": {
"text":"text",
"title":"",
"line1":"Journal",
"line2":"刊物"
}
}
Basically, the message is sent in the argument RemoteMessage along with your data object as Map, then you can manage the notification in onMessageReceived as in the snippet here
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
//you can get your text message here.
String text= data.get("text");
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
// optional, this is to make beautiful icon
.setLargeIcon(BitmapFactory.decodeResource(
getResources(), R.mipmap.ic_launcher))
.setSmallIcon(smallIcon) //mandatory
.......
/*You can read more on notification here:
https://developer.android.com/training/notify-user/build-notification.html
https://www.youtube.com/watch?v=-iog_fmm6mE
*/
}
reference: How to handle notification when app in background in Firebase

Firebase Notification & User Id

I'm using Firebase with an Android app (Auth, Database and Notification).
I'm trying to send notification from an external server (in nodejs) so an user can send a notification to another user.
So the android app memorize a list of UserId (the same ids from Firebase Auth) and then send this list to the nodejs server.
With this list, the server contact the url 'https://fcm.googleapis.com/fcm/send', but Firebase returns me a InvalidRegistration because i'm sending a list of userId and not the list of registration token created by firebase notification.
Should I memorize those tokens or there is a way to send notification with the user id ?
(And when I try with a list of tokens, of course it's working.)
var requestData = {
"registration_ids": userIds, //Problem is here
"data": {
"message": "A message"
}
};
request({
url: "https://fcm.googleapis.com/fcm/send",
method: "POST",
json: true,
headers: {
"Authorization": "key=firebaseKey",
"content-type": "application/json",
},
json: requestData
},
function(err, response, body) {
});
Yes, you can. For this you have to register these user Ids instead of device Id token. Then firebase recognized your user Ids.
#Override
public void onNewToken(#NonNull String token) {
super.onNewToken(token);
Log.d("user_token: ",token);
}

GoogleCloudMessaging Android

I am confused while implementing the upstream message using the new GoogleCloudMessaging APIs :
public void onClick(final View view) {
if (view == findViewById(R.id.send)) {
new AsyncTask() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
Bundle data = new Bundle();
data.putString("hello", "World");
String id = Integer.toString(msgId.incrementAndGet());
gcm.send(SENDER_ID + "#gcm.googleapis.com", id, data);
msg = "Sent message";
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
mDisplay.append(msg + "\n");
}
}.execute(null, null, null);
} else if (view == findViewById(R.id.clear)) {
mDisplay.setText("");
}
}
We send the messages(XMPP) to GCM server using the SENDER_ID id, so how can my third party server identify my device only with the SENDER_ID?
gcm.send(SENDER_ID + "#gcm.googleapis.com", id, data);
The code you posted sends a message from your device to your 3rd server, not to another device. Your server should establish a connection with the Cloud Connection Server, and since establishing that connection requires using SENDER_ID + "#gcm.googleapis.com" for user name, the GCM server can identify your 3rd party server.
When you 3rd party server sends a message to your device, it uses the Registration ID, which identifies your app on a specific device.
EDIT :
I may have misunderstood your question. If you are asking how does the 3rd party server know which device sent the upstream message to it, the message that your 3rd party server receives contains the Registration ID of the sender, as you can see here :
<message id="">
<gcm xmlns="google:mobile:data">
{
"category":"com.example.yourapp", // to know which app sent it
"data":
{
"hello":"world",
},
"message_id":"m-123",
"from":"REGID"
}
</gcm>
</message>
Even though you don't specify the Registration ID when you call gcm.send(...), GCM knows which device sent the message, so (assuming your app registered to GCM and therefore has a Registration ID) they can add the Registration ID to the message (I'm not sure if they add it on the client side before connecting the GCM server, or if the add it at the GCM server, but it doesn't really matter).

Categories

Resources