I'm using this code, when the app is in the foreground it was working perfectly. but the notification coming during app is in background Intent does not have any data.
Intent intent = new Intent(this, SplashActivity.class);
intent.putExtra(Constant.device_id,deviceId);
intent.putExtra(Constant.isFromPush,true);
intent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.default_notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title_)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
getString(R.string.app_name),
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(new Random().nextInt( 2000 ) /* ID of notification */, notificationBuilder.build());
To Handle intent data when app is in background you need to do something extra.
There should have "data" key in your response to get it in activity. Like,
{
"notification": {
"key_1": "value_1",
"key_2": "value_2"
},
"data": {
"key_1": "value_1",
"key_2": "value_2"
},
}
And you need to get the values inside your launching activity's onCreate method.
Launching activity is which <intent-filter> contains
<category android:name="android.intent.category.LAUNCHER" />
Receive data,
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
//bundle contains all info of "data" field of the notification
}
In background, app receives notification payload in the notification tray, and only handle data payload when the user taps on the notification
We have two type of Payload in case of send-downstream both are optional.
data
This parameter specifies the custom key-value pairs of the message's payload.
notification
This parameter specifies the predefined, user-visible key-value pairs of the notification payload.
[https://firebase.google.com/docs/cloud-messaging/http-server-ref#send-downstream][Find More detail here]
When you are in background, FCM will showing notification in system tray based on the info from notification payload. Title, message, and icon which used for the notification on system tray are get from the notification payload.
{
"notification": {
"title" : "title",
"body" : "body text",
"icon" : "ic_notification",
"click_action" : "OPEN_ACTIVITY_1"
}
}
You need to use data payload instead of notification payload ,your issue get resolved .
Here is the example JSON i'm reciving :
{
"to": "FCM registration ID",
"data": {
"someData" : "This is some data",
"someData2" : "etc"
}
}
Here is my java code.
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage == null)
return;
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
try {
JSONObject json = new
JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
Messages with both notification and data payload:
A message can also contains both notification and data payload. When these kind of messages are sent, it will be handled in two scenarios depending upon app state (background / foreground). For these message we can use both notification and data keys.
When in the background – Apps receive the notification payload in the notification tray, and only handle the data payload when the user taps on the notification.
When in the foreground – App receives a message object with both payloads available.
Related
I am working chat application. I want to show custom push Notification when message receives, when app is open and closed (not destroyed or killed) notification are received, below code is working fine, but when app is killed or destroyed from background custom push notification is not received in oreo and above
Here is code I Used
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
try {
context = getApplicationContext();
Map<String, String> data = remoteMessage.getData();
if ("message".equals(data.get("pushNotificationAction"))){
System.out.println("message");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),
0, intent, 0);
String mediatype = data.get("mediaType");
String mesageType= data.get("messageType");
String channel_id = createNotificationChannel(getApplicationContext());
mBuilder = new NotificationCompat.Builder(getApplicationContext(),channel_id)
.setSmallIcon(R.drawable.kisan_smoll_logo1)
.setCustomBigContentView(contentViewBig)
.setCustomContentView(contentViewBig)
.setContentIntent(contentIntent)
.setContentTitle(data.get("messageText"))
.setWhen(when)
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(NotificationManager.IMPORTANCE_MAX)
.setAutoCancel(true);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}catch(Exception e){
e.printStackTrace();
}
Sending JSON from server is below:
{
"message":{
"to": "FCMID",
"data" : {
"body" : "This is a Message!",
"title" : "Notifiation Message"
"mediaType":"IMAGE",
"messageType":"chat",
}
}
}
By sending data from server custom Fcm push notification is received in android when app is open, but when app is swipe from recent notifications are not received
I am converting a GCM-based messaging app to firebase. Messages are being sent to the app using the data-payload format. If my app is running, either in the foreground or background, the code in OnMessageRecieved runs and sets the notification title. But if the app is not running when the notification is recieved it does not display a title. I have tried adding a title to the data payload:
{
"data": {
"title": "My Title",
"message": "Text of the message",
}
}
and also have tried defining it in the AndroidManifest.xml following the format of defining the icon:
<meta-data android:name="com.google.firebase.messaging.default_notification_title" android:value="My Title"/>
but neither of these methods have worked.
public override void OnMessageReceived(RemoteMessage message)
{
try
{
SendNotification(message.GetNotification()?.Body, message.Data);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
void SendNotification(string messageBody, IDictionary<string, string> data)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
foreach (string key in data.Keys)
{
if (key == "message")
messageBody = data[key];
else
intent.PutExtra(key, data[key]);
}
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new Notification.Builder(this)
.SetSmallIcon(Resource.Drawable.smallicon)
.SetContentTitle(AppInfo.DisplayName)
.SetContentText(messageBody)
.SetAutoCancel(true)
.SetDefaults(NotificationDefaults.Sound | NotificationDefaults.Vibrate)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(0, notificationBuilder.Build());
}
Turns out OnMessageRecieved IS being run, the issue was with the setting of the title itself:
.SetContentTitle(AppInfo.DisplayName)
AppInfo.DisplayName is set in the OnCreate method of MainActivity. I replaced the variable with:
.SetContentTitle(ApplicationInfo.LoadLabel(PackageManager))
and that displays the app name as the title in notifications that are received when the app is not running. Thanks BobSnyder for pointing me in the right direction!
I've been developing android apps for a while now and all of them have FCM integrated in them and functioning properly.
I have this app that the onMessageReceived isn't fired unless the app is opened, if the app is closed and I receive a notification it opens from splash and follows the normal flow (it doesn't go to the Notifications activity).
N.B: all the testing I've done was from the Firebase Console
I really don't know why, any help would be appreciated.
Here's my code:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.wtf("RECEIVED","NOTIFICATION");
// TODO(developer): Handle FCM messages here.
Log.wtf(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.wtf(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.wtf(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
sendNotification("Notification");
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.icon)
.setContentTitle("FCM Message")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
Using Firebase, you can send two type of notifications message basically.
1. Notification messages : sometimes thought of as "display messages."
2. Data/Payload messages : which are handled by the client app.
both above Notification has different behaviour, depending upon if your app is in foreground or background.
1.Notification msg + Background : delivered to the notification tray
2.Notification msg + Foreground : onMessageReceived() on Android
3.Data msg + Background : apps receive the notification payload in the notification tray, and only handle the data payload when the user taps on the notification.
4.Data msg + Foreground : your app receives a message object with both payloads available.
For more clarification check this.
For sending Data/payload message using FCM console use Advance option and insert key and value.
I want to check notification data JSON object before its been shown to user
is that possible ?? and if it is possible how to do it
thanks for the help
Firstly parse and analyze json received in fcm service class and then display notification as required.
You can use this Service if you are using FCM.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
/**
* Called when message is received.
*
* #param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
// [START receive_message]
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
// [END_EXCLUDE]
// TODO(developer): Handle FCM messages here.
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());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
sendNotification("String From Data Payload");
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
remoteMessage contains the message which is received by the service. After receiving the message you can handle your data payload by using remoteData.getData() which is stored as a Map. You can use remote.getData().get("json_key") to get particular value for your json_key sent inside data payload.
After getting the data you can use the method sendNotification as follows:
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.logo)
.setContentTitle("FCM Message")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
in onMessageReceived of your fcm service check the json before passing it to notification
Android: How to bind Notification action to activity Dynamically in Android Manifest file?
Specially for fire-base integration.
Please give suggestion.Thank you
Recive Custom Message in Notification And According to KeyWork True Or false Or Your Specific Word go to Activity
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FirebaseMessageService";
Bitmap bitmap;
/**
* Called when message is received.
*
* #param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
//
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());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
//The message which i send will have keys named [message, image, AnotherActivity] and corresponding values.
//You can change as per the requirement.
//message will contain the Push Message
String message = remoteMessage.getData().get("message");
//imageUri will contain URL of the image to be displayed with Notification
String imageUri = remoteMessage.getData().get("image");
//If the key AnotherActivity has value as True then when the user taps on notification, in the app AnotherActivity will be opened.
//If the key AnotherActivity has value as False then when the user taps on notification, in the app MainActivity will be opened.
String TrueOrFlase = remoteMessage.getData().get("AnotherActivity");
//To get a Bitmap image from the URL received
bitmap = getBitmapfromUrl(imageUri);
sendNotification(message, bitmap, TrueOrFlase);
}
/**
* Create and show a simple notification containing the received FCM message.
*/
private void sendNotification(String messageBody, Bitmap image, String TrueOrFalse) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("AnotherActivity", TrueOrFalse);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setLargeIcon(image)/*Notification icon image*/
.setSmallIcon(R.drawable.firebase_icon)
.setContentTitle(messageBody)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(image))/*Notification with Image*/
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
This is AnotherActivity
// If a notification message is tapped, any data accompanying the notification
// message is available in the intent extras. In this project the launcher
// intent is fired when the notification is tapped, so any accompanying data would
// be handled here. If you want a different intent fired, set the click_action
// field of the notification message to the desired intent. The launcher intent
// is used when no click_action is specified.
//
// Handle possible data accompanying notification message.
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
if (key.equals("AnotherActivity") && value.equals("True")) {
Intent intent = new Intent(this, AnotherActivity.class);
intent.putExtra("value", value);
startActivity(intent);
finish();
}
}
}
This is The Data
{ "data": {
"image": "https://ibin.co/2t1lLdpfS06F.png",
"message": "Firebase Push Message Using API"
"AnotherActivity": "True"
},
"to" : "f25gYF3***********************HLI"
}
To achieve the functionality of opening an activity, upon receiving of notification, that activity should be given intent-filter in manifest, to listen for an action.
In the Notification, along with the payload, the action which the activity listens for, should be sent. In the Receiver, an Intent with such an action can be fired, which opens the activity, Even if app is in backgroud or closed.