Grouping of Notifications not working in Android 8.1 - push-notification

I am using FCM to send notifications on Android Device of 8.1 version.
I am trying to achieve the grouping of notifications , and i have achieved it.
Whenever first notification is in status bar and second notification arrives the first notification disappears. From Second notification on wards all the notifications are shown in the group as expected.
How to solve it ?
Posting Code Snipper below.
if ("FirstTime".equals(new SharedPrefsOperations(this).getPreferencesData("ActiveNotifs"))) {
// I AM EXECUTING THIS ONLY AT FIRST TIME , WHEN THE FIRST NOTIFICATION ARRIVES.
String tempData = new SharedPrefsOperations(this).getPreferencesData("ActiveNotifs");
Notification notification = new NotificationCompat.Builder(this, "MYAPP")
.setSmallIcon(R.mipmap.ic_static_notif)
.setContentTitle(content.getTitle())
.setContentText(tempMsg)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setGroup(notifGroup)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setChannelId(channel_id)
.setStyle(inboxStyle)
.setGroupSummary(true)
.build();
notificationManager.notify(id, notification);
new SharedPrefsOperations(this).storePreferencesData("ActiveNotifs", "1");
} else {
// I AM EXECUTING THIS FROM SECOND NOTIFICATION ONWARDS
String tempData = new
SharedPrefsOperations(this).getPreferencesData("ActiveNotifs");
Notification notification = new NotificationCompat.Builder(this, "MYAPP")
.setSmallIcon(R.mipmap.ic_static_notif)
.setContentTitle(content.getTitle())
.setContentText(tempMsg)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setGroup(notifGroup)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setChannelId(channel_id)
.setStyle(inboxStyle)
.build();
notificationManager.notify(id, notification);
new SharedPrefsOperations(this).storePreferencesData("ActiveNotifs", "1");
}

If you are using same id for notifying, it won't work. You need to use a different id for that
Update
Above Android 8.0 (Oreo) Notification Channels are compulsory. So add the notification channel like this. This should be done before notifying.
val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Android O requires a Notification Channel.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = context.getString(R.string.app_name)
// Create the channel for the notification
val mChannel = NotificationChannel("channel_id_sms", name, NotificationManager.IMPORTANCE_DEFAULT)
// Set the Notification Channel for the Notification Manager.
mNotificationManager.createNotificationChannel(mChannel)
}

Related

open specific activity and send data on click of a notification when app is killed

I have an application implemented with firebase push notifications.
I have a scenario where I open a NotiticatinDetails activity on click of the notification and show the notification message in a textview. It works fine when the app is in foreground.
But it doesn't navigate to NotiticatinDetails activity when the app is in kill state at the time of receiving notification. It launches MainActivity only. Instead, I want to launch NotiticatinDetails activity and show the notification message just like how I am doing it in the foreground case.
And when I click on back/close button in NotiticatinDetails activity it has to navigate to previous activity (MainActivity in app killed state) instead of closing the application.
This is how I am sending notification to NotiticatinDetails activity from my FirebaseService class. Calling below method in onMessageReceived method.
private void sendNotification(String msg) {
Intent notifyIntent = new Intent(ctx, NotificationDetailsActivity.class);
notifyIntent.putExtra("NotificationMessage", msg);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
mNotificationManager = (NotificationManager)
ctx.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent notifyPendingIntent = PendingIntent.getActivity(ctx, 0,
notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
ctx,
NOTIFICATION_CHANNEL_ID)
.setContentText(msg)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSmallIcon(android.R.drawable.ic_popup_reminder)
.setAutoCancel(true)
.setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL);
notificationBuilder.setContentIntent(notifyPendingIntent);
mNotificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
if (NotificationDetailsActivity.isVisible) {
NotificationDetailsActivity.notificationDetailsActivity.ToastNotify(msg);
}
}
Calling onNewIntent method in NotificationDetails activity as below.
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Bundle extras = intent.getExtras();
if(extras != null){
if(extras.containsKey("NotificationMessage")){
String msg = extras.getString("NotificationMessage");
TextView helloText = (TextView) findViewById(R.id.text_hello);
helloText.setText(msg);
}
}
}
I have added same onNewIntent method in MainActivity also but it doesn't receive the data.
Please help me out to navigate to NotificationActivity and show data when app is in killed state.

Xamarin.Forms push-notifications are transmitted very unreliably (late or not at all)

I am writing an Xamarin.forms based app which is currently running on android platform. It is the first time I need to use push-notifications. I followed a guide from microsoft (https://learn.microsoft.com/de-de/xamarin/android/data-cloud/google-messaging/remote-notifications-with-fcm?tabs=vswin)") to implement the notifications.
The target android version is 8.1 API 27. The app runs on a Samsung tab active 2, which has android 8.1.
I configured the app as seen in the tutorial. I push the messages through a defined channel and this channel is subscribed in the app. The messages are pushed by a server which triggers the rest call for the FCM api. The first day I did some tests the transmission worked very good and I would say it was (nearly) reliable.
The next day I implemented some other features and wanted to test the push notifications again. Then: I was very confused, the most messages were not delivered or VERY VERY late. I am not sure if all messages were transmitted, there went may be some lost.
For me the FCM service is a big blackbox where I can delegate some work and then I need to hope that the messages will be transmitted. I am very confused now.
I paste here some code, but it is nearly what you can find in the tutorial:
My Questions:
What can I do? Is there something to get some more information from the FCM what my messages are currently doing? Or are there some problems with the code?
This is run in the mainActivity:
if (this.IsPlayServicesAvailable())
{
// Creates a notification channel
this.CreateNotificationChannel();
//Console.WriteLine("InstanceID token: " + FirebaseInstanceId.Instance.Token);
// Subscribe to notification token
FirebaseMessaging.Instance.SubscribeToTopic("channel");
Log.Debug(TAG, "Subscribed to remote notifications");
}
This checks if the channel can be created and creates it: (is called in the mainActivity)
private void CreateNotificationChannel()
{
// The app is not running on Android 8.0 or higher
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
// Create a notification channel for publishing notifications
var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.Default)
{
Description = "Firebase Cloud Messages appear in this channel"
};
var notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
This checks if playServices are available: (also called in mainActivity)
public bool IsPlayServicesAvailable()
{
int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.Success)
{
if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode))
{
Log.Debug(TAG, GoogleApiAvailability.Instance.GetErrorString(resultCode));
}
else
{
Log.Debug(TAG, "This device has no compatible Google Play services APK - Download an APK from the Google Play Store or to enable it in the device's system settings!");
Finish();
}
return false;
}
else
{
Log.Debug(TAG, "Google Play Services are available.");
return true;
}
}
The last snipped is the service to handle a notification and inform the user:
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class CustomFirebaseMessagingService : FirebaseMessagingService
{
// Logging Tag
private static readonly string TAG = "CustomFirebaseMessagingService";
/* Handles data messages and notifications messages if the app is in foreground.
*
* Apps only have 10 seconds in which to handle an incoming Firebase Cloud Message.
* Any work that takes longer than this should be scheduled for background execution using a library such as the 'Android Job Scheduler' or the 'Firebase Job Dispatcher'.
*
*/
public override void OnMessageReceived(RemoteMessage message)
{
Log.Debug(TAG, "Message from: " + message.From);
// If the message data payload is not empty, display a notification
if (message.Data.Count > 0)
{
Log.Debug(TAG, "Data Payload: " + message.Data.ToString());
this.SendNotification(message.Data);
}
}
// Converts the incoming FCM message into a local notification
private void SendNotification(IDictionary<string, string> data)
{
Console.WriteLine("Push Message received");
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
if (data.TryGetValue("message", out string message))
{
foreach (var key in data.Keys)
{
intent.PutExtra(key, data[key]);
}
var pendingIntent = PendingIntent.GetActivity(this, MainActivity.NOTIFICATION_ID, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.NotificationIcon)
.SetContentTitle("TITEL")
.SetContentText(message)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManagerCompat.From(this);
notificationManager.Notify(MainActivity.NOTIFICATION_ID, notificationBuilder.Build());
}
}
}

FCM - Only 'display' push notification when app is in background

Currently, I have push notifications being sent and received in my Xamarin app. When I send a push notification the sneak peak dialogue is displayed when the app is in the foreground & also the background. I am trying to only visual display a push notification when the app is in the background. When the user is in the foreground the notification just sneaks into the HUD and is not displayed.
Here is my code:
Xamarin Android
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FCMMessagingService : FirebaseMessagingService
{
const string TAG = "MyFirebaseMsgService";
public override void OnMessageReceived(RemoteMessage message)
{
try
{
var _message = message.GetNotification().Body;
var _title = message.GetNotification().Title;
MainActivity.SendNotification(_title, _message);
}
catch (Exception e)
{
//Was NotificationType null? this should never be null anyways
}
}
}
API - Android Payload
return new JObject(
new JObject(
new JProperty("notification",
new JObject(
new JProperty("body", message),
new JProperty("title", title),
new JProperty("icon","toasticon"),
new JProperty("user", fromId != null ? fromId.ToString() : "")
)
),
new JProperty("data",
new JObject(
new JProperty("notificationtype", notificationType)
)
)
)
).ToString();
If you have followed the firebase setup for xamarin android
You might have read there that foreground notifications have to be displayed manually,
How to do that?
This is how
In the setup, you will have a class inheriting from FirebaseMessagingService
In that class, there will be a piece of code something like this():
var pendingIntent = PendingIntent.GetActivity(this,
MainActivity.NOTIFICATION_ID,
intent,
PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
.SetSmallIcon(Resource.Drawable.ic_stat_ic_notification)
.SetContentTitle("FCM Message")
.SetContentText(messageBody)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManagerCompat.From(this);
notificationManager.Notify(MainActivity.NOTIFICATION_ID,
notificationBuilder.Build());
This piece of code sends the notification to the Android tray, When in the foreground and hence if you comment this you will get the desired output.
Good luck!
In case of queries revert.

Show IconBadgeNumber after push notification while app background or closed (Xamarin.iOS)

In my Xamarin.iOS project I use Azure Notification Hub to send push notification to my application.
I can control my IconBadgeNumber with this code in AppDelegate class.
var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Badge, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
I can count number of my push notification when they come:
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
{
ProcessNotification(userInfo, false);
UIApplication.SharedApplication.ApplicationIconBadgeNumber = UIApplication.SharedApplication.ApplicationIconBadgeNumber + 1; ;
}
But it will work only if my application is opened. How I can count push notifications for IconBadgeNumber when my app is backgrouned or close?
The count of push notifications is up to your settings in the push service.Such as
Message message = Message.builder()
.setApnsConfig(ApnsConfig.builder()
.putHeader("apns-priority", "10")
.setAps(Aps.builder()
.setAlert(ApsAlert.builder()
.setTitle("$GOOG up 1.43% on the day")
.setBody("$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.")
.build())
.setBadge(42)
.build())
.build())
.setTopic("industry-tech")
.build();
You can set the number of badge setBadge(xxx).

PushNotification with custom parameter from android to IOS goes as just text

notification screenshot on IOS Hi I have been trying to send push-notification from android to ios with custom parameters required for my app. Tried sending it as hashmap as in the code above but did not receive that notification at all instead received default notification as :"you have 1 unread message".Also tried sending it as json(Please refer code ) but it goes as plain text and is displayed as json text in the notification to user as shown in the screen shot attached. Please help me with this so i can send notification with only "message" part displayed to user and other custom parameters to be used internally by app.
StringifyArrayList<Integer> userIds = new StringifyArrayList<Integer>();
userIds.add(userId1);
QBEvent event = new QBEvent();
event.setUserIds(userIds);
event.setEnvironment(QBEnvironment.DEVELOPMENT);
event.setNotificationType(QBNotificationType.PUSH);
event.setPushType(QBPushType.APNS);
JSONObject json = new JSONObject();
JSONObject json1 = new JSONObject();
try {
// standart parameters
json.put("text", message);
// custom parameters
json1.put("sellerName", sellerName);
json1.put("Buyer Name", buyerName);
json1.put("Type",type);
json.put("custom",json1 );
} catch (Exception e) {
e.printStackTrace();
}
//HashMap<String, Object> data = new HashMap<String, Object>();
//data.put("message", message);
// data.put("sellerName",sellerName);
//data.put("Type", type);
//event.setMessage(data);
event.setMessage(json.toString());
QBPushNotifications.createEvent(event).performAsync(new QBEntityCallback<QBEvent>() {
#Override
public void onSuccess(QBEvent qbEvent, Bundle bundle) {
System.out.println("QBPush Message success"+qbEvent.getMessage());
}
#Override
public void onError(QBResponseException e) {
// System.out.println(" QB Error in Push Message success");
e.printStackTrace();
}
});
If you need to send the universal push notification (the one that goes to all platforms, not only iOS or Android) then you need to omit PushType:
event.setPushType(QBPushType.APNS);
From doc:
https://quickblox.com/developers/Messages#Create_event
event[push_type]:
If not present - Notification will be delivered to all possible
devices for specified users.
If specified - Notification will be delivered to specified platform only
You can refer push notifications code sample page to receive more code snippets (Universal push notifications -> With custom parameters): https://quickblox.com/developers/SimpleSample-messages_users-android#Universal_push_notifications

Resources