Identify if an activity was opened from FCM notification click
I hope you know that FCM based messaging created two types of notification
Firstly, the notification that we create from on onMessageReceived()
method, the point to note here is that onMessageReceived()
will be triggered if the app is in foreground.
Secondly, FCM creates its own default notification when app is in background, in this case onMessageReceived()
is not intercepted and hence we cannot set a pending intent on our own.
Note : the above mentioned types comes to play when you are sending a "notification" push message to your app in the case of a me "data" message onMessageReceived()
is triggered irrespective of the app being in foreground or background (the notifications sent from FCM console are "notifications" type push messages)
Coming back to your question, it is not clear if you're sending a push message from FCM console or making a FCM server request, so let's make cases here.
- Message being sent by FCM Console :
send data payload from the advance section in notification panel on FCM which looks like this
when app is in foreground onMessageReceived()
will be intercepted
use the code below to receive the data payload
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Displaying data in log
//It is optional
//Calling method to generate notification
sendNotification(remoteMessage.getData());
}
//This method is only generating push notification
//It is same as we did in earlier posts
private void sendNotification(Map<String, String> messageBody) {
Intent intent = new Intent(this, SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
setNotificationRoute(messageBody),
PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(android.R.drawable.sym_def_app_icon)
.setContentTitle(messageBody.get("title"))
.setContentText(messageBody.get("text"))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
private Intent setNotificationRoute(Map<String, String> messageBody) {
Intent intent = null;
String type = messageBody.get("type");
if (type != null) {
switch (type) {
case "android": //intercept your payload here to create swit
intent = new Intent(this, MainActivity.class);
break;
default:
break;
}
}
return intent;
}
}
and if app is in background, then on notification click app will be opened on a "default" activity, you can set any activity as a default one by adding the following lines in the app manifest in the activity's intent filter:
<category android:name="android.intent.category.DEFAULT" />
inside this activity you can call to get intent extras and then get the data payload to decide on which activity you need to land on. The code is below
.
.
.
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
setNotificationRoute(getIntent().getExtras());
.
.
}
private void setNotificationRoute(Bundle extras) {
String type = extras.getString("type");
Intent intent = null;
if (type != null) {
switch (type) {
case "message":
String room = extras.getString("room");
intent = new Intent(this, MainActivity.class);
startActivity(intent);
break;
default:
break;
}
}
}
Message sent from FCM Server: the message sent from FCM consolse above is same as sending the below json body as post request to FCM server:
{ "notification": { "title": "Hi Tester", "text": "News for testing", "sound": "default", "badge": 0 }, "data":{ "type": "credits" }, "priority": "high", "to": "{{device_token}}" }
the process of intercepting the notifications will be same for this case.