I have created android application to receive push notification from server but it is not working.
When app is in foreground, it works perfectly. But when we force close app from system tray it does not work.
Below is my json code which I send to FCM.
{"to":"\/topics\/global","data":{"title":"Title","body":"Body"}}
Below is my android function
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.d("Msg", "Message received ["+remoteMessage+"]");
Map<String, String> data = remoteMessage.getData();
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
db.addData(data.get("body"));
Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
resultIntent.putExtra("message", data.get("body"));
showNotificationMessage(getApplicationContext(), data.get("title"), data.get("body"), "", resultIntent);
}
Below is code to show notification.
private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent);
}
I can not find any problem, can any one please help me.
Thank you very much in advance.
Edit :
I have solved my problem by changing phone, in samsung device code is working fine but its problem with MI device itself.
I have also got solution for MI devices, use below steps to enable auto start that application.
Go to settings --> permissions --> autostart. From there, pick the apps you want to receive notifications, and toggle the switch to turn it on.
As per the doc there are two possibilities when notification arrived.
Application is in foreground.
You will get notify in onMessageReceived, and you can get data in this method. You need to generate local notification in system tray.
Handle Notification
You have done this code as mentioned in question.
Application is in background.
You get notification in system tray. You don't need to generate notification here. You will get data in Intent of launcher Activity.
Handle Notification
Here is code of launcher activity
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent == null || intent.getExtras() == null) {
// your code to handle if there is no notification
} else {
// handle notification
String body = intent.getStringExtra("body");
String title = intent.getStringExtra("title");
//TODO your code to open activity as per notification
}
}
I have done this, and its works for me.
From here,
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.
And from this,
This includes messages that contain both notification and data payload (and all messages sent from the Notifications console). In these cases, the notification is delivered to the device's system tray, and the data payload is delivered in the extras of the intent of your launcher Activity
You might get complete help from receive message tutorial
Related
I am following this tutorial to implement Firebase Push Notification functionality within my app.
But I found one thing, if app is in foreground then only I am getting (showing) message in a Toast and TextView.
Other hand, If app is in background on tap neither I am not getting message to show in a TextView and Toast.
Whereas I would like to show message in Toast and TextView in both the situations (Either App is in Foreground or Background).
NOTE: I am pushing message from Firebase console itself.
Is it possible ?
MyFirebaseMessagingService.java
private void handleNotification(String message) {
if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
}else{
// If the app is in background, firebase itself handles the notification
}
}
MainActivity.java
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// checking for type intent filter
if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) {
// gcm successfully registered
// now subscribe to `global` topic to receive app wide notifications
FirebaseMessaging.getInstance().subscribeToTopic(Config.TOPIC_GLOBAL);
displayFirebaseRegId();
} else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
// new push notification is received
String message = intent.getStringExtra("message");
Toast.makeText(getApplicationContext(), "Push notification: " + message, Toast.LENGTH_LONG).show();
txtMessage.setText(message);
}
}
};
FCM has two types of messages, Notification and Data. 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 on your client app.
Below is the sample,
{
"to": “token ID”,
"notification": {
//params
},
"data": {
//params
}
}
Behaviour when the payload with types of messages,
Notification Messages
Foreground - onMessageReceived fired
Background - Notification appears on the System tray and handled by FCM
App not running - Notification appears on the System tray and handled by FCM
Data Messages
Foreground - onMessageReceived
Background - onMessageReceived
App not running - onMessageReceived
Both Notification and Data
Foreground - onMessageReceived
Background - Notification in the tray and the data payload will be handled via extras of the intent on tap
App not running - Notification in the tray and the data payload will be handled via extras of the intent on tap.
Hope it helps!
I am using Firebas mesaging service class. and Its working properly when app is running in foreground but when i clear this application from recent i am not able to access the push notification data for setting it on textview.
I want to store data in database when app is running in background.
I had Used Database to store the value directly but its not working.
public void onMessageReceived(RemoteMessage message) {
database=new SQLiteHelper(getApplicationContext());
database.open();
String image = message.getNotification().getIcon();
String title = message.getNotification().getTitle();
String text = message.getNotification().getBody();
String sound = message.getNotification().getSound();
int id = 0;
database.addQuotes(text,"Xyz");
}
In MainActivity.java in Oncreate method
Bundle extras = getIntent().getExtras();
if (extras != null) {
final String message = extras.getString("message");
quote_text.setText(message);
Toast.makeText(this, "A", Toast.LENGTH_SHORT).show();
}
But message shows null data.
based on this:
I want to store data in database when app is running in background
The service calls which extends FirebaseMessagingService has a method called onMessageReceived which is called when a push notification is received on the front-end (app) add your message to DB there!
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
.....
// parse and add your message to Db here!
Normally when your app is in the background, Android directs notification messages to the system tray. A user tap on the notification opens the app launcher by default.
This includes messages that contain both notification and data payload (and all messages sent from the Notifications console). In these cases, the notification is delivered to the device's system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.
But you can refer this answer on stackoverflow if you want to get notification data-messages in your app while in background.
You may also refer this
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")
......
when my app in foreground then the notification url link open automatically without user's any contribution.
Now,I want to keep notification in notification bar and when user press the notification that will open the url link.
One more thing I have to mention that,when my app in background it works fine.Notification arrive in notification bar.
I want same thing to do for foreground.
please help,
Thanks in advance.
my FirebaseMessagingServices
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if(remoteMessage.getData().size()>0){
String url = remoteMessage.getData().get("url");
Intent intent = new Intent("com.bellecarib_FCM-MESSAGE");
intent.putExtra("url",url);
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
localBroadcastManager.sendBroadcast(intent);
}
}
here is my MainActivity code
LocalBroadcastManager.getInstance(this).registerReceiver(mHandler, new IntentFilter("com.bellecarib_FCM-MESSAGE"));
if(getIntent().getExtras() != null){
for(String key: getIntent().getExtras().keySet()){
if(key.equals(("url"))){
mwebView.loadUrl(getIntent().getExtras().getString(key));
Toast.makeText(getApplicationContext(),"Opening The Notification Page",Toast.LENGTH_LONG).show();
}
}
}
The behaviour you are seeing , is when you send notification payload from FCM. If you want a customised behaviour, then send only a data payload and when you receive the message, throw up a notification manually. This means more work for your app (at the cost of customisation). Also data payloads are delivered with a normal priority which means if your device is in idle mode, then FCM Data payload messages are not delivered immediately and deferred till the next maintenance window (Read upon Android Doze mode and App Standby).
Hope this is clear
I have successfully implemented the push notification tutorial for Android. Once the notification is received it will immediately perform an action based on the json objects passed via the BroadcastReceiver.
However we would like that the action only be performed once the user clicks the push notification alert in the notification tray. Is this possible? From the tutorials we can choose which activity is opened via the subscribe method.
I am trying to determine when a particular push notification is clicked to launch the app. I am sending the pushes with a custom action and receiving them fine. When the notification is clicked to open the app for the first time, I receive the action and push notification data in the extras. However, once the app is already open / backgrounded, the extras never change. If I open the app from a different push notification OR open the app just from the app icon, the extras remain the same as the original notification that opened the app (or no extras if the app was opened originally just by the icon).
This is my code in onResume() method of my activity
Intent intentNotification = getIntent();
Bundle extras = intentNotification.getExtras();
if (extras!=null) {
String jsonData = extras.getString( "com.parse.Data" );
System.out.println("Message Data : "+jsonData);
}
Any one please help me on this problem..
I also went through the same situation while using Xtify for push notification
I applied a simple logic of creating static variable according to the need. when the specific operation id completed . in my case user registers , then I would make the static variable to empty (public static String MY_GLOBAL_VARIABLE=""). Unless the user doesn't register the variable contains the value
try to implement this logic ...
hope this can help to at least to start.
Try this....
public static String MY_JSON_DATA;
Intent intentNotification = getIntent();
Bundle extras = intentNotification.getExtras();
if (extras!=null) {
MY_JSON_DATA=extras.getString( "com.parse.Data" );
System.out.println("Message Data : "+MY_JSON_DATA);
}
// when open the app , use the value from MY_JSON_DATA and after clear it like MY_JSON_DATA=""
add this method into your Activity which is push notification open
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Bundle extras = intent.getExtras();
setIntent(intent);
if (extras!=null) {
String jsonData = extras.getString( "com.parse.Data" );
System.out.println("New Notification Data : "+jsonData);
String msg;
try {
JSONObject jMsg=new JSONObject(jsonData);
if (jMsg.has("alert")) {
msg=jMsg.getString("alert");
Util.SaveToSharedPref(LoginActivity.this, Constant.ShaPreNotification, Constant.ShaPreNotfMessage, msg);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
and onRecevie() method call one custom function which body is same as onNewIntent()
This is important because when app is completely closed i.e it is remove from recent apps /apps history at that time on receive method is called so it getting notification message.
and other time it call onNewIntent() method