FCM automatically displays the message to end-user devices on behalf of the client app. When user click on notification there is two conditions created
Notifications delivered when your app is in the background. In this case, the notification is delivered to the device’s system tray. A user tap on a notification opens the app launcher by default.
Messages with both notification and data payload, both background and foreground. In this case, 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.
if you want to open desired activity when app is in background and notification is contain only notification and without data playload then it is not posible.
But, if if you want to open desired activity when app is in background and notification is contain data playload then you can navigate the user to desired activity.
See Below Example for Open Desired Activity when Messages with data payload, both background and foreground Condition.
in my AndroidManifest launcher Activity is SplashActivity
<activity android:name=".activities.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
You can test notification on pushtry.com from Google FCM Tester.
Here is the format of playload data when send through pushtry.com
{
"to":"your_device_token",
"data": {
"title": "hello",
"message": "test message",
},
"priority":"high"
}
MyFirebaseMessagingService Class:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
private static int count = 0;
@Override
public void onNewToken(String s) {
super.onNewToken(s);
KeyManager.setSharedPreferenceString(getApplicationContext(), "fcm_token", s);
Log.e(TAG, "onNewToken: " + s);
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Here notification is recieved from server
try {
sendNotification(remoteMessage.getData().get("title"), remoteMessage.getData().get("message"));
} catch (Exception e) {
e.printStackTrace();
}
}
private void sendNotification(String title, String messageBody) {
Intent intent = new Intent(getApplicationContext(), SplashActivity.class);
//you can use your launcher Activity insted of SplashActivity, But if the Activity you used here is not launcher Activty than its not work when App is in background.
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//Add Any key-value to pass extras to intent
intent.putExtra("pushnotification", "yes");
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//For Android Version Orio and greater than orio.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel mChannel = new NotificationChannel("Sesame", "Sesame", importance);
mChannel.setDescription(messageBody);
mChannel.enableLights(true);
mChannel.setLightColor(Color.RED);
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
mNotifyManager.createNotificationChannel(mChannel);
}
//For Android Version lower than orio.
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, "Seasame");
mBuilder.setContentTitle(title)
.setContentText(messageBody)
.setSmallIcon(R.mipmap.ic_launcher_sesame)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_sesame))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setColor(Color.parseColor("#FFD600"))
.setContentIntent(pendingIntent)
.setChannelId("Sesame")
.setPriority(NotificationCompat.PRIORITY_LOW);
mNotifyManager.notify(count, mBuilder.build());
count++;
}
}
Now, when you recieved pushnotification in background condition and clicked on notification, notification is delivered to the
device’s system tray and Extras pass to your launcher Activity.
Check launcher Activity is with extras or empty and than navigate the user to desired Activity.
if you want to show your activity to only logged in user only than SplashActivity looks like Below:
public class SplashActivity extends AppCompatActivity {
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
try {
if (KeyManager.getSharedPreferenceBoolean(SplashActivity.this, "isLoggedIn", false)) {
if (getIntent().hasExtra("pushnotification")) {
Intent intent = new Intent(this, YourDesiredActivity.class);
startActivity(intent);
finish();
} else {
CheckLogin();
}
} else {
Intent i = new Intent(SplashActivity.this, LoginActivity.class);
startActivity(i);
finish();
}
} catch (Exception e) {
CheckLogin();
e.printStackTrace();
}
}
private void CheckLogin() {
if (KeyManager.getSharedPreferenceBoolean(SplashActivity.this, "isLoggedIn", false)) {
Intent i = new Intent(SplashActivity.this, MainActivity.class);
startActivity(i);
} else {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent i = new Intent(SplashActivity.this, LoginActivity.class);
startActivity(i);
finish();
}
}, 2500);
}
}
}
Logic in SplashActivty for navigate the user in different Activity as per Condition.
When user open application in normal flow without clicking on pushnotification, getIntent().hasExtra(“pushnotification”) is null so command goes to catch block and CheckLogin() method checked for already login or not.
But user entered by clicking pushnotification then getIntent().hasExtra(“pushnotification”) is not null and he will go to desired Activity.