Identify if an activity was opened from FCM notification click

前端 未结 3 902
广开言路
广开言路 2021-01-05 02:45

I am using the fcm console to send messages to all of devices that have my app installed, the notifications don\'t have any extra payload only the notification message.

3条回答
  •  -上瘾入骨i
    2021-01-05 03:01

    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.

    1. 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 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 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:

    
    

    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;
            }
          }
        }
    
    1. 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.

提交回复
热议问题