FCM Push Notifications are only displayed when app is in background - android

I am using the following code to receive and display push notifications:
override fun onMessageReceived(remoteMessage: RemoteMessage) {
if (remoteMessage.getNotification() != null) {
var title : String = remoteMessage.notification!!.title!!
var message : String = remoteMessage.notification!!.body!!
val intent = Intent(this, LoginCommonActivity::class.java)
intent.addflags(intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
var builder: NotificationCompat.Builder;
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
//val notificationManager = NotificationManagerCompat.from(applicationContext)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel =
NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannels(notificationChannel)
builder = NotificationCompat.Builder(applicationContext, notificationChannel.id)
} else {
builder = NotificationCompat.Builder(applicationContext)
}
builder = builder.setSmallIcon(R.drawable.ic_app_logo_black)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setDefaults(Notification.DEFAULT_ALL)
.setVibrate(longArrayOf(1000, 1000, 1000, 1000))
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)
notificationManager.notify(System.currentTimeMillis().toInt(), builder.build())
}
}
But PNs' are only displayed when app is in background or closed. Debugging the FCMMessagingService, I can see that PNs' are being sent by the server and received in onMessageReceive(). It appears that the notify() method is not working, or something else in the code is failing.
As per this article, FCM notifications are handled by the internal Firebase service when the app is in background, else they are received in onMessageReceived() of FirebaseMessagingService when the app is in the foreground, and we have to manually display them with notify(). But this isn't working.
We've already seen this problem before here, here, here and here. But that was maybe when the old GCM features were still present in FCM. By this time FCM must have been completely overhauled.
My questions are:
What is the default protocol for handling push notifications if they arrive when the app is in the foreground?
Looking at other popular apps - WhatsApp, Google Pay, Zomato - I do not ever recall seeing a push notification when the app is in the foreground. Does this mean that push notifications never appear in the tray when the app is in the foreground?
If so, then what is the reason for having the NotificationManager.notify() function in the first place? If push notifications only appear when the app is in the background, and they are auto-handled by the Firebase service, then why is this method there at all? Is this just a relic of the old GCM library?
Can someone please point out where the problem is?

I will try to answer all your questions
First notification are of two types
1): Notification Payload ( Your's case)
2): Data Payload
1): Notification Payload
In notification payload
-If App in Background ( FCM will handle push notifications it self )
-If App in Foreground ( payload will receive in onMessageReceived we have to write our own logic to weather show notification or not )
2): Data Payload
In data payload
-If App in Background ( payload will receive in onMessageReceived we have to write our own logic to weather show notification or not )
-If App in Foreground ( payload will receive in onMessageReceived we have to write our own logic to weather show notification or not )
For Notification Please try using updated code from android guide using Compat library
https://developer.android.com/training/notify-user/build-notification#groovy

Just remove "notification" key from payload and provide only "data" key.
Application handles notification messages only if the app is in foreground but it handles data messages even if the application is in background or closed.
more info: https://stackoverflow.com/a/38850030/19892188

Related

Android - push notifications: purpose of FirebaseMessagingService class?

I've seen two tutorials about sending push messages from server with PHP to android devices through firebase cloud messaging and it works fine. But both tutorials have the FirebaseMessagingService class and I don't understand what's the purpose of it?? They don't explain a bit about it.
This is it:
class FirebaseMessagingService : com.google.firebase.messaging.FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
showNotification(remoteMessage!!.data["message"]!!)
}
private fun showNotification(message: String) {
val i = Intent(this, MainActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT)
val builder = NotificationCompat.Builder(this)
.setAutoCancel(true)
.setContentTitle("FCM Test")
.setContentText(message)
.setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
.setContentIntent(pendingIntent)
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.notify(0, builder.build())
}
}
Can I send push notifications from android with it? I just need to send push messages from PHP so can I delete it? The overview of my project is already messy and hard to follow and I don't want any useless stuff in there. Thanks in advance
This class is responsible for handling income message. The function onMessageReceived will be invoked when there is incoming data message no matter your app is in foreground or background. More specifically, this method is for you to customize the handling of key:value pair in data payload
You can leave it there if you are not going to do any special handling.
Please read here for more information.

How to prevent android quick reply notification from being stuck in loading?

My app uses the Android N's new quick-reply feature to quickly take notes from a fixed notification, without having the user to open an activity.
However, I would like the notification to be reset to its initial state after the user sends the quick reply message, without having to dismiss the notification.
Here is my code:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? createChannel() : "").setSmallIcon(android.R.mipmap.sym_def_app_icon).setContentTitle("My Awesome App").setContentText("Doing some work...").setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
android.support.v4.app.RemoteInput remoteInput = new RemoteInput.Builder(BookmarkCreatorReceiver.TXT_REPLY).setLabel("Reply").build();
Intent replyIntent = new Intent(this, BookmarkCreatorReceiver.class);
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(this, 0, replyIntent, 0);
NotificationCompat.Action action = new NotificationCompat.Action.Builder(android.R.drawable.ic_dialog_email, "Bookmark", replyPendingIntent).addRemoteInput(remoteInput).build();
NotificationCompat.Action actionQuick = new NotificationCompat.Action.Builder(android.R.drawable.ic_dialog_email, "Quick", replyPendingIntent).build();
builder.addAction(action);
builder.addAction(actionQuick);
}
startForeground(NOTIFICATION_ID, builder.build());
The problem is that once the user sends a message and the Broadcast receiver is called, the notification stays in the loading state like this:
How can I remove the loading message, without having to discard the notification?
Per the Notifications in Android N blog post:
After you’ve processed the text, you must update the notification by calling notify() with the same id and tag (if used). This is the trigger which hides the Direct Reply UI and should be used as a technique to confirm to the user that their reply was received and processed correctly.
Also note:
For most templates, this should involve using the new setRemoteInputHistory() method which appends the reply to the bottom of the notification.
This ensures that users see the text they entered was properly handled.

Android O Notification for Direct reply message

We are migrating to Notification Channel system in Android O, we noticed that once Channel is created, it's properties cannot be changed.
We have the following scenario,
- Notification channel is created with,
NotificationChannel channel = new NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_HIGH);
/**
* Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
* intents.
*/
we have messaging style with history of messages
User receives a message in the notification bar - Notification sound plays.
User replies to message, we've implemented BroadcastReceiver to receive replied message and update the notification again with the latest message, But due to the channel importance being High, notification sound played again which should not play for better user experience.
We tried using addHistoricMessage() for the replied message, which shows the same behavior
Is there any way to prevent Android from playing sound for notification for the replied messages.
code:
Channel creation:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = title;
NotificationChannel channel = new NotificationChannel(MESSAGE_CHANNEL, name, NotificationManager.IMPORTANCE_HIGH);
android.app.NotificationManager notificationManager = context.getSystemService(android.app.NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
Notification builder:
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, MESSAGE_CHANNEL);
NotificationCompat.MessagingStyle style = new NotificationCompat.MessagingStyle(displayName)
.setConversationTitle(conversation.isGroup() ? conversation.getTitle(context) : null);
style.addMessage(message, timestamp, sender);
.
.
.
.
builder.setStyle(style);
builder.setShowWhen(true);
builder.setGroup(MESSAGING_GROUP_LABEL);
builder.setColor(ContextCompat.getColor(context, conversation.getColorSet().getPrimaryColorId()));
setVisibility(builder);
builder.setAutoCancel(true);
setPriority(builder, NotificationCompat.PRIORITY_MAX);
setCategory(builder, Notification.CATEGORY_MESSAGE);
setSmallIcon(builder, R.drawable.ic_stat_ic_notif);
NotificationManagerCompat.from(context).notify(conversation.getConversationId(), notificationId, builder.build());
messageRepliedReceiver:
same notification builder is used with previous notificationId
If existing notification is amended with extra message then you can use on the same builder:
notificationBuilder.setOnlyAlertOnce(true);
This works even for Notifications in Android O Notification Channels. It will prevent vibration, sound, but it will still peek if Channel setting was Urgent (IMPORTANCE_HIGH).
This possible solution was found in this post that has other great ideas about handling "history of messages" notification: Android: How to use MessagingStyle for notifications without caching messages

Force Grouping of Notifications?

According to the Notification Design Guidelines documentation:
If the same app sends four or more notifications and does not specify a grouping, the system automatically groups them together.
So I tested this out:
However, it only works when you have 4 or more notifications. I notice Messenger does this when you only have two notifications:
So my question is, can I tell the Android to always group my notifications like Messenger does? Or does Messenger use the setGroup() method that I would prefer not to use...
It's doable.
The concept is to make a group notification builder for grouping up notifications and apply same groupKey to other notification builder. And call NotificationManagerCompat.notify() to build group notification beforehand. So these notifications with same groupKey will group together.
You can add group notification builder with NotificationCompat.Builder.setGroup("GROUP_KEY") and NotificationCompat.Builder.setGroupSummary(true).
And add NotificationCompat.Builder.setGroup("GROUP_KEY") to other notifications.
val groupKey = "GROUP_KEY"
val groupBuilder = NotificationCompat.Builder(context, "CHANNEL_ID")
groupBuilder.apply {
setAutoCancel(true)
...
setGroupSummary(true)
setGroup(groupKey)
}
val builder = NotificationCompat.Builder(context, "CHANNEL_ID")
groupBuilder.apply {
setAutoCancel(true)
...
setGroup(groupKey)
}
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.notify(NOTIFICATION_ID, groupBuilder.build())
notificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, builder.build())

How to make push notification without internet

me and my colleague are trying to show "push notification" message in mobile device. Colleague is telling that it can´t be done without Google Cloud Messaging but I think - why use any server for that?
We want something like this:
How our application will work is:
- user has app on background
- ajax request is made (request to our server)
- server response is: You have 1 new message
- message is showed in top strip on mobile.
Of course, the message can be showed without internet.. My GF had mobile app "Pou"... when he pooped notification was displayed... Just I dont get it why to use any Google service for that?
Can somebody direct me pls?
You should use Notification to show "push notification".
private void showNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setAutoCancel(true)
.setTicker(getString(R.string.notification_ticker_text))
.setContentText(getString(R.string.notification_content_text))
.setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, 0))
.setWhen(System.currentTimeMillis())
.setContentTitle(getString(R.string.app_name))
.setDefaults(Notification.DEFAULT_ALL);
Notification notification = builder.build();
((NotificationManager) this.getSystemService(NOTIFICATION_SERVICE)).notify(0, notification);
}

Categories

Resources