FCM Push notifications display raw json even after implementing dats messages - android

Following is the json that I am trying to send from the firebase console
{
"message": {
"token": "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data": {
"Nick": "Mario",
"body": "great match!",
"Room": "PortugalVSDenmark"
}
}
}
My code in onMessageReceived is as follows
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
String name = remoteMessage.getData().get("Nick").toString();
String body = remoteMessage.getData().get("body").toString();
String room = remoteMessage.getData().get("Room").toString();
String messageBody = name
+ " "
+ body
+ " "
+ room;
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle("Zone")
.setContentText(messageBody)
.setAutoCancel(true)
.setSmallIcon(R.mipmap.ic_launcher)
/*Notification with Image*/;
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
Every time I send the above json from firebase console it does not even enter the if condition because the remoteMessage.getData().size() is not greater than zero.
Why is this happening though I am sending a data payload?
Also when the notification is received I want to create a sentence from the raw json and display it . E.g "Nick liked a picture"
When the notification comes through only the json is displayed.
Been struggling with this for a long time .
Any help will be appreciated. Thank you

Try this.
String nick,body,room, fullString;
if(!remoteMessage.getData().isEmpty()){
Log.d(TAG, "Notification Message Data: " + remoteMessage.getData());
nick=remoteMessage.getData().get("Nick");
body=remoteMessage.getData().get("body");
room=remoteMessage.getData().get("Room");
Log.d(TAG, "All data: " + nick+","+body+","+room);
fullString = "Anything you want"+nick+"anything";
//then use the string anywhere
}

Related

How to get the background notification title and body inside the application [duplicate]

I need to use non-collapsible notification by Firebase. For that I am using data-message like this:
{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data" : {
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
},
}
This message is interpreted in the onMessageReceived() method.
I still want to display this data-message in the tray just like notification-messages are displayed by the system automatically.
How to I achieve this? I cannot find documentation on this.
Thanks!
You can retrieve the values from your data payload in onMessageReceived() by calling RemoteMessage.getData(), then .get("<KEY_HERE>"). Like so:
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.d(TAG, "onMessageReceived()");
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
String dataTitle = remoteMessage.getData().get("data_title");
String dataBody = remoteMessage.getData().get("data_body");
sendNotification(dataTitle, dataBody);
}
You have to then build and display the Notification yourself. Like so:
private void sendNotification(String title, String body) {
Notification notif = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(body)
.build();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(0, notif);
}

Getting a java.lang.numberformatexception invalid int null in android [duplicate]

I'm building an Android app which will receive push notifications. I've got Firebase Cloud Messaging setup and pretty much working, such that I can send the following payload to a valid token and the notification and data are received.
Using url https://fcm.googleapis.com/fcm/send
{
"to":"<valid-token>",
"notification":{"body":"BODY TEXT","title":"TITLE TEXT","sound":"default"},
"data":{"message":"This is some data"}
}
My app receives it correctly and can deal with it.
The only slight wrinkle is that I get the following exception thrown in the debug:
Error while parsing timestamp in GCM event
java.lang.NumberFormatException: Invalid int: "null"
at java.lang.Integer.invalidInt(Integer.java:138)
...
It doesn't crash the app, it just looks untidy.
I've tried adding a timestamp item to the main payload, the notification, the data, and also tried variations such as time but can't seem to get rid of the exception (and google as I might, I can't find an answer).
How do I pass the timestamp so it stops complaining?
Edited: Here is my onMessageReceived method, but I think the exception is thrown before it gets here
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
//TODO Handle the data
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
Thanks in advance,
Chris
Even though notification is apparently a supported element (according to the Firebase web docs), the only way I could get rid of the exception was to remove it entirely, and use the data section only, and then in my app create a notification (rather than letting firebase do the notification).
I used this site to work out how to raise the notifications: https://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
My notification now looks like the following:
$fields = array("to" => "<valid-token>",
"data" => array("data"=>
array(
"message"=>"This is some data",
"title"=>"This is the title",
"is_background"=>false,
"payload"=>array("my-data-item"=>"my-data-value"),
"timestamp"=>date('Y-m-d G:i:s')
)
)
);
...
<curl stuff here>
...
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
My onMessageReceived looks like this:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
which calls handleDataMessage which looks like this:
private void handleDataMessage(JSONObject json) {
Log.e(TAG, "push json: " + json.toString());
try {
JSONObject data = json.getJSONObject("data");
String title = data.getString("title");
String message = data.getString("message");
boolean isBackground = data.getBoolean("is_background");
String timestamp = data.getString("timestamp");
JSONObject payload = data.getJSONObject("payload");
// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
if (!NotificationUtils.isBackgroundRunning(getApplicationContext())) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(ntcAppManager.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
} else {
// app is in background, show the notification in notification tray
Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
resultIntent.putExtra("message", message);
showNotificationMessage(getApplicationContext(), title, message, timestamp, resultIntent);
}
} catch (JSONException e) {
Log.e(TAG, "Json Exception: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
this then calls showNotificationMessage
/**
* Showing notification with text only
*/
private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent);
}
And subsequently notificationUtils.showNotificationMessage
public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) {
showNotificationMessage(title, message, timeStamp, intent, null);
}
public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
// Check for empty push message
if (TextUtils.isEmpty(message))
return;
// notification icon
final int icon = R.mipmap.ic_launcher;
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
mContext,
0,
intent,
PendingIntent.FLAG_CANCEL_CURRENT
);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
mContext);
final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
+ "://" + mContext.getPackageName() + "/raw/notification");
showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
playNotificationSound();
}
private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.addLine(message);
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(inboxStyle)
.setWhen(getTimeMilliSec(timeStamp))
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(ntcAppManager.NOTIFICATION_ID, notification);
}
More detail in the link above, and it's a lot of handling but at least the exception's gone and I'm in control of the notifications.
I've updated com.google.firebase:firebase-messaging to 17.3.4 and issue disappeared.
I was running into this same error, I resolved by adding a ttl value to the payload.
{
"to":"<valid-token>",
"notification":{"body":"BODY TEXT","title":"TITLE TEXT","sound":"default"},
"data":{"message":"This is some data"},
"ttl": 3600
}
I had the same problem, I've just set "body" parameter in notification and error dissapeared.
What worked for me:
Upgrading, not only firebase-messaging, but all Firebase libraries to the last version. In android/app/build.gradle:
dependencies {
implementation "com.google.firebase:firebase-core:16.0.0" // upgraded
implementation "com.google.firebase:firebase-analytics:16.0.0" // upgraded
implementation 'com.google.firebase:firebase-messaging:17.3.4' // upgraded
// ...
implementation "com.google.firebase:firebase-invites:16.0.0" // upgraded
// ...
}
Not all of them are at version 17.x
Format below (no notification body, nor are there any arrays) fixed the timestamp exception for me:
{
"to": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"data": {
"message": "message",
"title": "hello",
}
}
Tested fine with http://pushtry.com/
The only reason I included the long 'eeee...' is that is the exact size of my token.
replace
"notification" : {
"title" : "title !",
"body" : "body !",
"sound" : "default"
},
"condition" : "'xxx' in topics",
"priority" : "high",
"data" : {
....
by (remove notification) :
{
"condition" : "'xxxx' in topics",
"priority" : "high",
"data" : {
"title" : "title ! ",
"body" : "BODY",
......
}
And on you code :
Replace :
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
remoteMessage.getNotification().getTitle();
remoteMessage.getNotification().getBody();
}
by
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
remoteMessage.getData().get("title");
remoteMessage.getData().get("body");
}
In my case My error was "AndrodManifest.xml"
I miss one service (actually Android studio's firebase assistant is missing my permission. :) )
original
<service android:name=".fcm.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
</application>
solution
<service android:name=".fcm.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name=".fcm.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>

Android/Firebase - Error while parsing timestamp in GCM event - Null timestamp

I'm building an Android app which will receive push notifications. I've got Firebase Cloud Messaging setup and pretty much working, such that I can send the following payload to a valid token and the notification and data are received.
Using url https://fcm.googleapis.com/fcm/send
{
"to":"<valid-token>",
"notification":{"body":"BODY TEXT","title":"TITLE TEXT","sound":"default"},
"data":{"message":"This is some data"}
}
My app receives it correctly and can deal with it.
The only slight wrinkle is that I get the following exception thrown in the debug:
Error while parsing timestamp in GCM event
java.lang.NumberFormatException: Invalid int: "null"
at java.lang.Integer.invalidInt(Integer.java:138)
...
It doesn't crash the app, it just looks untidy.
I've tried adding a timestamp item to the main payload, the notification, the data, and also tried variations such as time but can't seem to get rid of the exception (and google as I might, I can't find an answer).
How do I pass the timestamp so it stops complaining?
Edited: Here is my onMessageReceived method, but I think the exception is thrown before it gets here
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
//TODO Handle the data
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
Thanks in advance,
Chris
Even though notification is apparently a supported element (according to the Firebase web docs), the only way I could get rid of the exception was to remove it entirely, and use the data section only, and then in my app create a notification (rather than letting firebase do the notification).
I used this site to work out how to raise the notifications: https://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
My notification now looks like the following:
$fields = array("to" => "<valid-token>",
"data" => array("data"=>
array(
"message"=>"This is some data",
"title"=>"This is the title",
"is_background"=>false,
"payload"=>array("my-data-item"=>"my-data-value"),
"timestamp"=>date('Y-m-d G:i:s')
)
)
);
...
<curl stuff here>
...
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
My onMessageReceived looks like this:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
which calls handleDataMessage which looks like this:
private void handleDataMessage(JSONObject json) {
Log.e(TAG, "push json: " + json.toString());
try {
JSONObject data = json.getJSONObject("data");
String title = data.getString("title");
String message = data.getString("message");
boolean isBackground = data.getBoolean("is_background");
String timestamp = data.getString("timestamp");
JSONObject payload = data.getJSONObject("payload");
// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
if (!NotificationUtils.isBackgroundRunning(getApplicationContext())) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(ntcAppManager.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
} else {
// app is in background, show the notification in notification tray
Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
resultIntent.putExtra("message", message);
showNotificationMessage(getApplicationContext(), title, message, timestamp, resultIntent);
}
} catch (JSONException e) {
Log.e(TAG, "Json Exception: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
this then calls showNotificationMessage
/**
* Showing notification with text only
*/
private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent);
}
And subsequently notificationUtils.showNotificationMessage
public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) {
showNotificationMessage(title, message, timeStamp, intent, null);
}
public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
// Check for empty push message
if (TextUtils.isEmpty(message))
return;
// notification icon
final int icon = R.mipmap.ic_launcher;
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
mContext,
0,
intent,
PendingIntent.FLAG_CANCEL_CURRENT
);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
mContext);
final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
+ "://" + mContext.getPackageName() + "/raw/notification");
showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
playNotificationSound();
}
private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.addLine(message);
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(inboxStyle)
.setWhen(getTimeMilliSec(timeStamp))
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(ntcAppManager.NOTIFICATION_ID, notification);
}
More detail in the link above, and it's a lot of handling but at least the exception's gone and I'm in control of the notifications.
I've updated com.google.firebase:firebase-messaging to 17.3.4 and issue disappeared.
I was running into this same error, I resolved by adding a ttl value to the payload.
{
"to":"<valid-token>",
"notification":{"body":"BODY TEXT","title":"TITLE TEXT","sound":"default"},
"data":{"message":"This is some data"},
"ttl": 3600
}
I had the same problem, I've just set "body" parameter in notification and error dissapeared.
What worked for me:
Upgrading, not only firebase-messaging, but all Firebase libraries to the last version. In android/app/build.gradle:
dependencies {
implementation "com.google.firebase:firebase-core:16.0.0" // upgraded
implementation "com.google.firebase:firebase-analytics:16.0.0" // upgraded
implementation 'com.google.firebase:firebase-messaging:17.3.4' // upgraded
// ...
implementation "com.google.firebase:firebase-invites:16.0.0" // upgraded
// ...
}
Not all of them are at version 17.x
Format below (no notification body, nor are there any arrays) fixed the timestamp exception for me:
{
"to": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"data": {
"message": "message",
"title": "hello",
}
}
Tested fine with http://pushtry.com/
The only reason I included the long 'eeee...' is that is the exact size of my token.
replace
"notification" : {
"title" : "title !",
"body" : "body !",
"sound" : "default"
},
"condition" : "'xxx' in topics",
"priority" : "high",
"data" : {
....
by (remove notification) :
{
"condition" : "'xxxx' in topics",
"priority" : "high",
"data" : {
"title" : "title ! ",
"body" : "BODY",
......
}
And on you code :
Replace :
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
remoteMessage.getNotification().getTitle();
remoteMessage.getNotification().getBody();
}
by
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
remoteMessage.getData().get("title");
remoteMessage.getData().get("body");
}
In my case My error was "AndrodManifest.xml"
I miss one service (actually Android studio's firebase assistant is missing my permission. :) )
original
<service android:name=".fcm.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
</application>
solution
<service android:name=".fcm.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name=".fcm.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>

Error when push notification by postman but not when send by Firebase console [duplicate]

I'm building an Android app which will receive push notifications. I've got Firebase Cloud Messaging setup and pretty much working, such that I can send the following payload to a valid token and the notification and data are received.
Using url https://fcm.googleapis.com/fcm/send
{
"to":"<valid-token>",
"notification":{"body":"BODY TEXT","title":"TITLE TEXT","sound":"default"},
"data":{"message":"This is some data"}
}
My app receives it correctly and can deal with it.
The only slight wrinkle is that I get the following exception thrown in the debug:
Error while parsing timestamp in GCM event
java.lang.NumberFormatException: Invalid int: "null"
at java.lang.Integer.invalidInt(Integer.java:138)
...
It doesn't crash the app, it just looks untidy.
I've tried adding a timestamp item to the main payload, the notification, the data, and also tried variations such as time but can't seem to get rid of the exception (and google as I might, I can't find an answer).
How do I pass the timestamp so it stops complaining?
Edited: Here is my onMessageReceived method, but I think the exception is thrown before it gets here
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
//TODO Handle the data
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
Thanks in advance,
Chris
Even though notification is apparently a supported element (according to the Firebase web docs), the only way I could get rid of the exception was to remove it entirely, and use the data section only, and then in my app create a notification (rather than letting firebase do the notification).
I used this site to work out how to raise the notifications: https://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
My notification now looks like the following:
$fields = array("to" => "<valid-token>",
"data" => array("data"=>
array(
"message"=>"This is some data",
"title"=>"This is the title",
"is_background"=>false,
"payload"=>array("my-data-item"=>"my-data-value"),
"timestamp"=>date('Y-m-d G:i:s')
)
)
);
...
<curl stuff here>
...
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
My onMessageReceived looks like this:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
which calls handleDataMessage which looks like this:
private void handleDataMessage(JSONObject json) {
Log.e(TAG, "push json: " + json.toString());
try {
JSONObject data = json.getJSONObject("data");
String title = data.getString("title");
String message = data.getString("message");
boolean isBackground = data.getBoolean("is_background");
String timestamp = data.getString("timestamp");
JSONObject payload = data.getJSONObject("payload");
// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
if (!NotificationUtils.isBackgroundRunning(getApplicationContext())) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(ntcAppManager.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
} else {
// app is in background, show the notification in notification tray
Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
resultIntent.putExtra("message", message);
showNotificationMessage(getApplicationContext(), title, message, timestamp, resultIntent);
}
} catch (JSONException e) {
Log.e(TAG, "Json Exception: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
this then calls showNotificationMessage
/**
* Showing notification with text only
*/
private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent);
}
And subsequently notificationUtils.showNotificationMessage
public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) {
showNotificationMessage(title, message, timeStamp, intent, null);
}
public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
// Check for empty push message
if (TextUtils.isEmpty(message))
return;
// notification icon
final int icon = R.mipmap.ic_launcher;
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
mContext,
0,
intent,
PendingIntent.FLAG_CANCEL_CURRENT
);
final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
mContext);
final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
+ "://" + mContext.getPackageName() + "/raw/notification");
showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
playNotificationSound();
}
private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.addLine(message);
Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(inboxStyle)
.setWhen(getTimeMilliSec(timeStamp))
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(ntcAppManager.NOTIFICATION_ID, notification);
}
More detail in the link above, and it's a lot of handling but at least the exception's gone and I'm in control of the notifications.
I've updated com.google.firebase:firebase-messaging to 17.3.4 and issue disappeared.
I was running into this same error, I resolved by adding a ttl value to the payload.
{
"to":"<valid-token>",
"notification":{"body":"BODY TEXT","title":"TITLE TEXT","sound":"default"},
"data":{"message":"This is some data"},
"ttl": 3600
}
I had the same problem, I've just set "body" parameter in notification and error dissapeared.
What worked for me:
Upgrading, not only firebase-messaging, but all Firebase libraries to the last version. In android/app/build.gradle:
dependencies {
implementation "com.google.firebase:firebase-core:16.0.0" // upgraded
implementation "com.google.firebase:firebase-analytics:16.0.0" // upgraded
implementation 'com.google.firebase:firebase-messaging:17.3.4' // upgraded
// ...
implementation "com.google.firebase:firebase-invites:16.0.0" // upgraded
// ...
}
Not all of them are at version 17.x
Format below (no notification body, nor are there any arrays) fixed the timestamp exception for me:
{
"to": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"data": {
"message": "message",
"title": "hello",
}
}
Tested fine with http://pushtry.com/
The only reason I included the long 'eeee...' is that is the exact size of my token.
replace
"notification" : {
"title" : "title !",
"body" : "body !",
"sound" : "default"
},
"condition" : "'xxx' in topics",
"priority" : "high",
"data" : {
....
by (remove notification) :
{
"condition" : "'xxxx' in topics",
"priority" : "high",
"data" : {
"title" : "title ! ",
"body" : "BODY",
......
}
And on you code :
Replace :
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
remoteMessage.getNotification().getTitle();
remoteMessage.getNotification().getBody();
}
by
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
remoteMessage.getData().get("title");
remoteMessage.getData().get("body");
}
In my case My error was "AndrodManifest.xml"
I miss one service (actually Android studio's firebase assistant is missing my permission. :) )
original
<service android:name=".fcm.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
</application>
solution
<service android:name=".fcm.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name=".fcm.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>

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

Categories

Resources