How to merge push notifications in FirebaseMessagingService. I tried almost everything but nothing seems to work. For every new Data object it issues a new notification. The Log where I print number of notifications print 0.
Is there any method where I can track if there is any unread notification in notification drawer with the same notificationId, so I can merge the new one with it?
Any help will be appreciated.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
private static final String actionLiked = "liked";
mNumber=0;
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
ArrayList<String>notificationString= new ArrayList<>();
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());
Log.d(TAG, "Number of notifications" +mNumber);
Map<String, String> dataFromCloud = remoteMessage.getData();
String action = dataFromCloud.get("action");
switch (action) {
case actionLiked:
notificationString.add(action);
Intent intent = new Intent(this, MainActivity.class);
sendNotification(action, intent);
break;
default:
break;
}
}
}
private void sendNotification(String messageTitle, Intent intent) {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
String[] events = new String[6];
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setNumber(++numMessages);
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
for (int i=0; i < notificationString.size(); i++) {
inboxStyle.addLine(notificationString.get(i));
}
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}}
As no one posted an answer to this question I came up with an answer myself. This might not be the most optimized way of merging notifications but it worked for me like a charm. Have a look at my blog post.
Here is my FirebaseMessagingService class :
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
private static final String actionLiked = "liked";
private static final int NOTIFICATION_ID = 1593;
private final String GROUP_KEY = "GROUP_KEY_RANDOM_NAME";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
ArrayList<String> notificationString = new ArrayList<>();
if (remoteMessage.getData().size() > 0) {
Map<String, String> dataFromCloud = remoteMessage.getData();
String action = dataFromCloud.get("action");
String userName = dataFromCloud.get("userName");
switch (action) {
case actionLiked:
notificationString.add(action);
Intent intent = new Intent(this, LikeActivity.class);
String message = userName + " liked your photo.";
sendNotification(message, intent);
break;
default:
break;
}
}
}
@TargetApi(Build.VERSION_CODES.M)
private void sendNotification(String messageBody, Intent intent) {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
Intent onCancelNotificationReceiver = new Intent(this, CancelNotificationReceiver.class);
PendingIntent onCancelNotificationReceiverPendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0,
onCancelNotificationReceiver, 0);
String notificationHeader = this.getResources().getString(R.string.app_name);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
StatusBarNotification[] notifications = manager.getActiveNotifications();
for (int i = 0; i < notifications.length; i++) {
if (notifications[i].getPackageName().equals(getApplicationContext().getPackageName())) {
Log.d("Notification", notifications[i].toString());
Intent startNotificationActivity = new Intent(this, NotificationCenterActivity.class);
startNotificationActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, startNotificationActivity,
PendingIntent.FLAG_ONE_SHOT);
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentTitle(notificationHeader)
.setContentText("Tap to open")
.setAutoCancel(true)
.setStyle(getStyleForNotification(messageBody))
.setGroupSummary(true)
.setGroup(GROUP_KEY)
.setContentIntent(pendingIntent)
.setDeleteIntent(onCancelNotificationReceiverPendingIntent)
.build();
SharedPreferences sharedPreferences = getSharedPreferences("NotificationData", 0);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(String.valueOf(new Random(NOTIFICATION_ID)), messageBody);
editor.apply();
notificationManager.notify(NOTIFICATION_ID, notification);
return;
}
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Notification notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentTitle(notificationHeader)
.setContentText(messageBody)
.setAutoCancel(true)
.setGroup(GROUP_KEY)
.setContentIntent(pendingIntent)
.setDeleteIntent(onCancelNotificationReceiverPendingIntent)
.build();
SharedPreferences sharedPreferences = getSharedPreferences("NotificationData", 0);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(String.valueOf(new Random(NOTIFICATION_ID)), messageBody);
editor.apply();
notificationManager.notify(NOTIFICATION_ID, notificationBuilder);
}
private NotificationCompat.InboxStyle getStyleForNotification(String messageBody) {
NotificationCompat.InboxStyle inbox = new NotificationCompat.InboxStyle();
SharedPreferences sharedPref = getSharedPreferences("NotificationData", 0);
Map<String, String> notificationMessages = (Map<String, String>) sharedPref.getAll();
Map<String, String> myNewHashMap = new HashMap<>();
for (Map.Entry<String, String> entry : notificationMessages.entrySet()) {
myNewHashMap.put(entry.getKey(), entry.getValue());
}
inbox.addLine(messageBody);
for (Map.Entry<String, String> message : myNewHashMap.entrySet()) {
inbox.addLine(message.getValue());
}
inbox.setBigContentTitle(this.getResources().getString(R.string.app_name))
.setSummaryText("Tap to open");
return inbox;
}
}
Clear the saved data from Shared Preferences when user clicks on notification or delete the notification. To do this create a broadcast Receiver which will clear all the data saved by you. Call this in onCreate of the activities which can be opened from notifications.
code for broadcast receiver is as follows
public class CancelNotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences = context.getSharedPreferences("NotificationData", 0);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear();
editor.apply();
}}
Please feel free to suggest any edits so that I can optimize it further. Also if there is any better way of doing it then please write it down below. Hope this will help someone.