Not going to onMessageRecieved when the app is closed - android

I am using push notifications and they work fine when i am inside the app. But when app is in background . When notification arrives , i need it to go to onMessageRecieved because i am setting a condition like :
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
String type = data.getString("type");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
Log.d(TAG, "Type: " + type);
sendNotification(message, type);
}
private void sendNotification(String message, String type) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this);
//Set all notifcation properties etc
if (type.equals(Constants.GROUP_NOTIFICATION)) {
Intent intent = new Intent(this, MainActivity.class);
mBuilder.setContentIntent(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}else {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(Keys.NOTIFICATION_TYPE, Constants.QUESTION_NOTIFICATION);
mBuilder.setContentIntent(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}
}
}
For question Push Notification when it comes to the mainactivity by checking intent data it shoud be redirected to the questionActivity but since intent data is never set , it stays in mainactivity.
So my question is , how do i get data from the notification?

Well since i didn't get answers on my post so i figured out the problem my self . Did some searching and found out that there are two types of payloads. Data and notification . And if u have the notification payload than if your app is in background . Android will create a notification itself and will not called onMEssageRecieved . So i went to my server code and simply removed the notification payload part :) and now onMessagerecieved gets called.

Related

Specific activity not opening from notification click when the app is not in foreground(app is in recents, not killed!)

I want to open a specific activity on notification click. But when the application is in the background, it doent open. I am not even passing the extras(ie, the data). I just want to open the activity and according to user logged in, i do some tasks. I even tried to open my default launcher activity on the notification click and send the user to notification activity from there. Here's the code of my default launcher activity:
PS: I am sending the message from the firebase console, but it only has title and body.
(This is the function i call after doing my network task:)
if (list.size()!=0){
for (int i=0;i<list.size();i++){
Users u=list.get(i);
//Toast.makeText(LoginActivity.this, "Logging in...", Toast.LENGTH_SHORT).show();
final Intent intent;
Bundle b=new Bundle();
// This is the solution i found to check whether the extras has the package name or not! But it doesnt seem to work.
if (Splashscreen.this.getIntent().getExtras() != null){
if (Splashscreen.this.getIntent().hasExtra("pushnotification") || Splashscreen.this.getIntent().getExtras().containsKey("com.tracecost")){
System.out.println("From notification----------->");
intent=new Intent(Splashscreen.this,NotificationReceivedActivity.class);
b.putString("pushnotification","yes");
}
else{
intent=new Intent(Splashscreen.this, ProjectSelection.class);
}
}
else{
intent=new Intent(Splashscreen.this, ProjectSelection.class);
}
b.putSerializable("user",u);
b.putSerializable("projectlist",plist);
intent.putExtras(b);
//logginDialog.dismiss();
Handler handler=new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
startActivity(intent);
finish();
}
},3500);
}
}
}```
You can redirect from the Firebase notification when the app is in Foreground or Background as far as you send in data.
I will provide you an example of how to redirect between activities based on key received from the notification, firebase magically handles the rest.
P.S: If you want to handle the activity that is already open in the background, use taskAffinity to play around.
Handle the Firebase data through FirebaseMessagingService:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
System.out.println("MESSAGE BODY :" + remoteMessage.toString());
if (remoteMessage.getData().size() > 0) {
//getting the title and the body
String redirect;
String title = remoteMessage.getData().get("message_title");
String body = remoteMessage.getData().get("message_body");
redirect = remoteMessage.getData().get("redirect");
String event_id = remoteMessage.getData().get("event_id");
System.out.println("PUSH MESSAGE = " + remoteMessage.toString());
JSONObject jsonData = new JSONObject(remoteMessage.getData());
System.out.println("RESPONSE :" + jsonData.toString());
if (redirect != null) {
sendNotification(title, body, event_id, redirect);
} else {
redirect = "";
sendNotification(title, body, event_id, redirect);
}
}
}
private void sendNotification(String title, String body, String event_id, String redirect) {
Intent backIntent = new Intent();
PendingIntent pendingIntent;
if (redirect.contentEquals("CHAT")) {
backIntent = new Intent(MyFirebaseMessagingService.this, ChatScreen.class);
backIntent.putExtra("item_id", event_id);
}
if (redirect.contentEquals("EVENT") || redirect.contentEquals("INVITATION")) {
backIntent = new Intent(MyFirebaseMessagingService.this, Event_Summary.class);
backIntent.putExtra("event_id", event_id);
}
backIntent.putExtra("MODE", "FIRE_NOTIFICATION");
backIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(backIntent);
pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
}
This works only when app is in foreground. When app is in background, it considers only Notification data from payload and ignores data part. This leads to no control to the app as notification type messages will be handled by system alone. Only option is to use an external server of your own or send from a rest client.
Firebase console sends only Notification messages(more info here Firebase) but you can use your own server or Firebase API to send Data messages.
Data messages work for Foreground as well as Background app states.
A sample curl to trigger a push notification will look like:
curl -X POST \
https://fcm.googleapis.com/fcm/send \
-H 'Authorization: key=YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-H 'cache-control: no-cache' \
-d '{
"data": {
"title":"TITLE",
"message":"Notification Content",
"custom_key": "custom_value"
},
"registration_ids": ["DEVICE_PUSH_TOKEN"]
}'
You can pass your custom key-value pair as well and get them in onMessageReceived method.
Note: In this approach, you have to create the notification which will be visible in the system tray. Sample code will look like:
// Create an explicit intent for an Activity in your app
Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setAutoCancel(true);
You can find more on this in the official documentation
Hope this helps!

FCM Push Notification Android receiving 2 notifications in the background

I'm having a problem using the FCM Push Notification Messaging Service, as I've overridden the handleIntent() method to receive the notification when the app is in the foreground. I am also using the onMessageReceived() method.
But when the app is in the background, I will receive 2 notifications, which one of them only opens up the app and runs the MainActivity while the other is opening up the app how I want it to.
FYI: The notification I receive when I am in the foreground is exactly how I want it to open.
This is the code I've written below :
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private final String NOTIFICATION_TYPE = "type";
private final String NOTIFICATION_ID = "id";
private final String NOTIFICATION_TYPE_PRODUCT_DETAIL = "productdetail";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String title = remoteMessage.getNotification().getTitle();R
String body = remoteMessage.getNotification().getBody();
String token = remoteMessage.getFrom();
Log.d("FireBase TAG: ", token);
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d("FireBaseMessageService","FireBase Data payload : " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
#Override
public void handleIntent(Intent intent) {
super.handleIntent(intent);
String type = intent.getExtras().getString(NOTIFICATION_TYPE, "");
int id = 0;
try {
id = Integer.valueOf(intent.getExtras().getString(NOTIFICATION_ID, ""));
} catch (NumberFormatException e) {
e.printStackTrace();
}
//Intents
Intent mainIntent = MainActivity.newIntent(this);
Intent editProfileIntent = EditProfileActivity.newIntent(this);
Intent settingsIntent = SettingsActivity.newIntent(this);
Intent productIntent = ProductActivity.newNotificationIntent(this, id, false, true);
if (UserManager.getSingleton().isUserLoggedIn(getApplicationContext())) {
PendingIntent pendingIntent;
if (type.equalsIgnoreCase(NOTIFICATION_TYPE_PRODUCT_DETAIL)) {
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(mainIntent);
stackBuilder.addNextIntent(productIntent);
editProfileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_ONE_SHOT);
}
else {
pendingIntent = PendingIntent.getActivity(this, 0, productIntent,
PendingIntent.FLAG_ONE_SHOT);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(intent.getExtras().getString("gcm.notification.title"))
.setContentText(intent.getExtras().getString("gcm.notification.body"))
.setDefaults(NotificationCompat.DEFAULT_VIBRATE)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(0, builder.build());
}
}
}
I have deleted the NotificationCompat.Builder from the onMessageReceived() method.
But I am still receiving two notifications in the background.
App Gradle :
compile 'com.google.firebase:firebase-core:11.4.2' //Firebase
compile 'com.google.firebase:firebase-messaging:11.4.2' //Firebase Cloud Messaging
I've tried searching for a solution online but unluckily there isn't a solution pointing to Android.
You are handling your Notification stuff into handleIntent(Intent intent). You should probably remove super.handleIntent(intent); to prevent the Firebase system to handle notification while the app is in background.
Solution: remove super.handleIntent(intent);
Just make a sendnotification() method and set whatever parameters you want to pass like body i.e sendnotification(String body). Use pending intent to start you activity and when you click on notification your app parse the data to the launcher activity which is defined in manifest, so once you have data in your launcher activity you can send data to other activity using intent.
I think the .setContentText("") is getting called more than 1 times and are you getting same notification two times?
The notification which works perfectly is generated by your code but when your application is not in foreground android system will generate the notification for you. In this case when you don't have the control to send data in your intent that you were sending to open your desired Activity.
In this case, you have to do some modification on your servers payload. You have to add click_action in your payload, this is how android system will identify the destination activity.
Payload Example:
{ "notification": {
"title":"Notification title",
"body":"Notification body",
"click_action":"<Your_destination_activity>",
}, "data":{
"param1":"value1",
"param2":"value2"
},
"priority":"high",
}
Reference:
https://firebase.google.com/docs/cloud-messaging/http-server-ref
yes,
When you app in background you will receive the push at system tray so system tray will create push with notification title and message.
and when you click on the push your initial launcher activity (which mentioned as launcher in manifest) will open.
you can get your notification data at you launcher activity (bundle).
private void handlePush() {
Intent intent = null;
if (bundle.getString("push_type") != null && bundle.getString("push_type").length() > 0) {
switch (bundle.getString("push_type")) {
case PUSH_TYPE_FOLLOW_USER: {
intent = new Intent(this, ProfileExternalActivity.class);
intent.putExtra(Constants.USER_ID, Integer.parseInt(bundle.getString("id")));
intent.putExtra(Constants.FROM_PUSH_NOTIFICATION_SPLASH, true);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
break;
}
}
if (intent != null)
startActivity(intent);
finish();
}
}
and you need to check activty have data or not
if (bundle != null)
handlePush();
else //your next activity
FYI : https://firebase.google.com/docs/cloud-messaging/android/receive
or
you can get payload object instead of data object inside notification , if you have payload object in your notification object, push all time received at your onMessageReceived().
for people still having this issue:
Here is a hack to prevent this behavior. I've looked all over and there seems to be minimal info about this, but if you save the actual message being sent in shared preferences and then do a check against that value in onRecieve, you can easily prevent this. The only downside is that your user can't send the exact same message two times in a row in the form of a notification (but that would be annoying anyway). example:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
SharedPreferences Settings = getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = Settings.edit();
message = remoteMessage.getNotification().getBody();
from = remoteMessage.getFrom(); //this comes through as the topic, oddly...
if(from.equals("/topics/"+userID+deviceID+"all")) {
if(!message.equals(Settings.getString("messageall",null))) {//this filters any dupe messages
utils.postNotification(title, message, context, extra, "messages");//create notification
editor.putString("messageall", message);//always update to the last message
editor.commit();
}
}
}

onMessageSent of FirebaseMessagingService is not called accordingly

I am trying to use FCM to send UpStream Message, so I followed the tutorial on google and it works.
As shown in the code below in MainActivity, I send Upstream message when the button is clicked, then in MyAndroidFirebaseMsgService I should see a Log message as shown
below in MyAndroidFirebaseMsgService.
But what happen is, the Log messages in MyAndroidFirebaseMsgService in onMessageSent in do not get displayed even I kept pressing the button several times.
the Log message in MyAndroidFirebaseMsgService in onMessageSent can be displayed only if sent a downstream messagefrom FCM to the App, in this case, both the Logs in
in MyAndroidFirebaseMsgService will be displayed.
Please let me know why the Log message in onMessageSent is not getting displayed once there is an UpStream message sent?and how to fix it.
Mainactivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtnSendUpstreamMsg = (Button) findViewById(R.id.btn_send_upstream_message);
mBtnSendUpstreamMsg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FirebaseMessaging fm = FirebaseMessaging.getInstance();
fm.send(new RemoteMessage.Builder("673xxxxx" + "#gcm.googleapis.com")
.setMessageId("2")
.addData("my_message", "Hello World")
.addData("my_action","SAY_HELLO")
.build());
}
});
}
MyAndroidFirebaseMsgService:
public class MyAndroidFirebaseMsgService extends FirebaseMessagingService {
private final static String TAG = MyAndroidFirebaseMsgService.class.getSimpleName();
#Override
public void onMessageSent(String s) {
super.onMessageSent(s);
Log.d(TAG, "onMessageSent: upstream message");
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "onMessageReceived: downstream message");
//Log data to Log Cat
Log.d(TAG, "onMessageReceived->From: " + remoteMessage.getFrom());
Log.d(TAG, "onMessageReceived->Notification Message Body: " + remoteMessage.getNotification().getBody());
//create notification
createNotification(remoteMessage.getNotification().getBody());
}
private void createNotification( String messageBody) {
Intent intent = new Intent( this , ResultActivity.class );
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent resultIntent = PendingIntent.getActivity( this , 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri notificationSoundURI = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mNotificationBuilder = new NotificationCompat.Builder( this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Android Tutorial Point FCM Tutorial")
.setContentText(messageBody)
.setAutoCancel( true )
.setSound(notificationSoundURI)
.setContentIntent(resultIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, mNotificationBuilder.build());
}
}
Yes, is possible to send a Firebase messaging push notification and receive it in all app life cycles using onMessageReceived.
But is necessary to change the default Firebase behaviour, intercepting the intent request before everything else.
** IMPORTANT NOTE **
This was a pretty stupid idea from Firebase by remove the developers processment capability when the FCM message arives with the notification message format, but not for data message.
This created a bunch of "workarounds" in many solutions, which made the analythics and everything else being messed up.
If I had designed this solution, I would always call the onMessageReceived method with a completion handle. Let the developer decide what to do (free tip for you, Firebase).
Use onMessageReceived is the correct way to do. This method is the only one who brings RemoteMessage object, that have every information what you need. It was designed for it. You are on correct path.
** HOW TO DO **
In your Firebase Class MyAndroidFirebaseMsgService, which extends FirebaseMessagingService, override the public method handleIntent to intercep the intent request before Firebase catch it.
#Override
public void handleIntent(Intent intent){
if(intent.hasExtra("google.message_id")){
intent = handleFirebaseIntent(intent);
}
super.handleIntent(intent);
}
After, transform the notification message package into an data message, removing all "gcm.notification.%" and "gcm.n.%" extras from intent, and translating "gcm.notification.title", "gcm.notification.body" and "gcm.notification.image" elements into what you need:
// Thank you Google, for that brilliant idea to treat notification message and notification data
// differently on Android, depending of what app life cycle is. Because of that, all the developers
// are doing "workarounds", using data to send push notifications, and that's not what you planned for.
// Let the developers decide what to do on their apps and ALWAYS deliver the notification
// to "onMessageReceived" method. Its simple, is freedom and its what the creative ones need.
private Intent handleFirebaseIntent(Intent intent){
//printIntentExtras(intent);
String FCM_TITLE_KEY = "gcm.notification.title";
String FCM_BODY_KEY = "gcm.notification.body";
String FCM_IMAGE_KEY = "gcm.notification.image";
String title = intent.getStringExtra(FCM_TITLE_KEY);
String body = intent.getStringExtra(FCM_BODY_KEY);
String image = intent.getStringExtra(FCM_IMAGE_KEY);
// Remove the key extras that identifies an Notification type message
Bundle bundle = intent.getExtras();
if (bundle != null) {
for (String key : bundle.keySet()) {
if (key.startsWith("gcm.notification.") || key.startsWith("gcm.n."))
{
intent.removeExtra(key);
}
}
}
Boolean isTitleEmpty = StringUtils.isNullOrEmpty(title);
Boolean isBodyEmpty = StringUtils.isNullOrEmpty(body);
Boolean isImageEmpty = StringUtils.isNullOrEmpty(image);
// Notification title and body has prevalence over Data title and body
if(
!isTitleEmpty || !isBodyEmpty || !isImageEmpty
){
// This is my personalized translation method, designed for my solution.
// Probably you gonna need to do it by your own
String contentData = intent.getStringExtra(Definitions.PUSH_NOTIFICATION_CONTENT);
Map<String, Object> content;
if(StringUtils.isNullOrEmpty(contentData)){
content = new HashMap<String, Object>();
content.put(Definitions.NOTIFICATION_ID, new Random().nextInt(65536) - 32768);
content.put(Definitions.NOTIFICATION_CHANNEL_KEY, "basic_channel" );
} else {
content = JsonUtils.fromJson(new TypeToken<Map<String, Object>>(){}.getType(),contentData);
}
if(!isTitleEmpty) content.put(Definitions.NOTIFICATION_TITLE, title);
if(!isBodyEmpty) content.put(Definitions.NOTIFICATION_BODY, body);
if(!isImageEmpty){
content.put(Definitions.NOTIFICATION_BIG_PICTURE, image);
content.put(Definitions.NOTIFICATION_LAYOUT, NotificationLayout.BigPicture.toString());
}
contentData = JsonUtils.toJson(content);
intent.putExtra(Definitions.PUSH_NOTIFICATION_CONTENT, contentData);
}
//printIntentExtras(intent);
return intent;
}
private void printIntentExtras(Intent intent){
Bundle bundle;
if ((bundle = intent.getExtras()) != null) {
for (String key : bundle.keySet()) {
System.out.println(key + " : " + (bundle.get(key) != null ? bundle.get(key) : "NULL"));
}
}
}
You can check my entire solution here.

intent with FCM not working when app is in background(android)

I am using FCM to push notification. I am passing intent to launch new activity when notification is clicked.when app is in foreground,app works fine and intent launch new activity, but when app is in background, it does not launch new activity but launch instance of default activity.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Displaying data in log
//It is optional
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getBody());
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, SecActivity.class);
intent.putExtra("started_from","notification");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Firebase Push Notification")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
Hope you are trying to launch the mainactivity when the message is received. When the app is resumed from background your current activity is getting cleared.
From the documentation for FLAG_ACTIVITY_CLEAR_TOP:
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
Try removing this flag.
I too had this same problem but i managed to have it fix with this ,
In your default activity mentioned in the manifest do this in the onCreate
if (bundle != null) {
if ((String) bundle.get("tag") != null) {
String tag = (String) bundle.get("tag");
if (tag.equals("abc")) {
Intent intent = new Intent(SplashActivity.this, MessageDetailsActivity.class);
startActivity(intent);
} else if (tag.equals("def")) {
openSpecificActivity(tag, (String) bundle.get("id"));
}
} else {
Intent i = new Intent(SplashActivity.this, HomeActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}
i got a solution for that.
just put below code in oncreate method of launcher activity.
if (bundle != null) {
String value = bundle.getString("key");
if (value != null) {
startActivity(new Intent(MainActivity.this, secActivity.class));
}
}
when app is in background or killed,FCM will not call onmessagerecieved method,but it will send data to system tray to display notification.so datapayload(sent from fcm console) will not be handled by onmessagerecieved method.when user click on notification,it will launch default activity of app and datapayload will be passed by intent .so making change in oncreate method of launcher activity(as above)we can get datapayload even when app is in background or killed.(ex key is sent by fcm console).when app is in foreground datapayload and will be handled by onmessagerecieved method of fcm service.
Based upon Antinio's answer
https://stackoverflow.com/a/37845174/4454119
Why is this happening?
There are two types of messages in FCM (Firebase Cloud Messaging):
display-messages: These messages trigger the onMessageReceived() callback only when your app is in foreground
data-messages: Theses messages trigger the onMessageReceived() callback even if your app is in foreground/background/killed
Firebase team have not developed a UI to send data-messages to your devices, yet.
So you need to use data-messages..
In FCM you have two types of messages
Notification Messages
Data Messages
Use notification messages when you want FCM to handle displaying a notification on your client app's behalf. Use data messages when you want to process the messages in your client app.
If you need to process your message before sending it to the system tray, it's better to use Data messages, as for these types of messages, the callback first reaches the onMessageRecieved method before going to the system tray.
Use this:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
IN YOUR SERVICE
"to": token,
"notification": {
"title": "Title,
"body": "Body"
},
"data" : {
"update": "yes"
}
IN ANDROID KOTLIN
val intent = Intent(this,MainActivity::class.java)
intent.putExtra("update","yes")
......

Getting number instead of text for android notification

I have implemented android notification in my application and it is working fine except that it shows a number instead of the actual message body. Here is teh screen shot of what I am getting,
This is the code I have,
public static final int MESSAGE_NOTIFICATION_ID = 435345;
private int MESSAGE_TYPE ;
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
String type = data.getString("type");
if(type.equalsIgnoreCase("Load Messages"))
{
MESSAGE_TYPE = Global.NOTIFICATION_LOAD_MESSAGE;
EventBus.getDefault().post(new HandyManEvents.ReloadMessages(true));
}
else
{
MESSAGE_TYPE = Global.NOTIFICATION_LOAD_LIVE_JOBS;
}
createNotification(from, message);
}
// Creates notification based on title and body received
private void createNotification(String title, String body) {
Context context = getBaseContext();
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.putExtra("menuFragment", MESSAGE_TYPE);
PendingIntent pending= PendingIntent.getActivity(context, 0,notificationIntent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher).setContentTitle(title)
.setContentIntent(pending)
.setContentText(body);
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(MESSAGE_NOTIFICATION_ID, mBuilder.build());
}
Any clue whats going wrong here?
Updated
When app is running in foreground I am seeing this behaviour. This is the bundle I got from notification,
Bundle[{type=Load Messages, notification=Bundle[{e=1, body=You have a new message, icon=app_icon, title=New Message}], collapse_key=com.company.app}]
How to extract the title and body from Bundle?
Thanks.
You are uing google play services APIs to capture GCM messages. The class in which this code belongs is the one that extends GcmListenerService and you're overriding onMessageReceived(String from, Bundle data) which takes the sender ID as the first argument (from) and that what appears in your notification as you assigning it as a title.
You need to parse the bundle in a correct way to be able to get the data and that depends on the payload the server sends. You can see which key is available in the bundle by logging it
for (String key : bundle.keySet()){
Log.d(TAG, key + " = " + bundle.get(key));
}

Categories

Resources