Firebase console: How to specify click_action for notifications

老子叫甜甜 提交于 2019-11-27 06:46:15
Micha F.

This is a duplicate of this question: Firebase FCM notifications click_action payload

But the answer that was accepted by the author of this question just states that it is not possible with Firebase Console, but it is - with an easy workaround. This answer by diidu to the same question explains the workaround I would use.

UPDATE:
To elaborate on his answer:

Add a helper class (or implement startActivity() method somehow):

public class ClickActionHelper {
    public static void startActivity(String className, Bundle extras, Context context){
        Class cls;
        try {
            cls = Class.forName(className);
        }catch(ClassNotFoundException e){
            //means you made a wrong input in firebase console
        }
        Intent i = new Intent(context, cls);
        i.putExtras(extras);
        context.startActivity(i);
    }
}

In the launcher-activity of your app, call a mehtod to check any new intents in onCreate() and onNewIntent() (onNewIntent() is only called instead of onCreate() if Activity is launched with single-top flag):

@Override
protected void onCreate(Bundle bundle) {
    [...]
    checkIntent(getIntent());
 }

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    [...]
    checkIntent(intent);
}

public void checkIntent(Intent intent) {
       if (intent.hasExtra("click_action")) {
        ClickActionHelper.startActivity(intent.getStringExtra("click_action"), intent.getExtras(), this);
       }
}

And in onMessageReceived():

 public void onMessageReceived(RemoteMessage remoteMessage) {
     Map<String, String> data = remoteMessage.getData();        
     if (data.containsKey("click_action")) {
         ClickActionHelper.startActivity(data.get("click_action"), null, this);
     }
 }

To send a notification with firebase console, put a key-value-pair as custom data like this:

Key: click_action
Value: <fully qualified classname of your activity>

Now when a notification is received and clicked on, it will open your activity. If your app is in foreground, it will also immediately change to the activity - it would probably be good to ask the user if he wants to go to this activity or not (by showing a dialog in onMessageReceived()).

I have used handleIntent(Intent intent) method to handle intent and move to that particular screen. Below is my code which is working perfectly even when the app is in background :

FCMMessagingService.java which extends FCMMessagingService

@Override
    public void handleIntent(Intent intent) {
        super.handleIntent(intent);

     Intent i = null;
     String value_action = "";

      if (intent.getExtras() != null) {
          if (key.equals("click_action")) {
                value_action = intent.getExtras().getString(key);
            }

          i = new Intent(FCMMessagingService.this, MainActivity.class);
          i.putExtra("notificationFlag", value_action);
          i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

      }
     PendingIntent pendingIntent = PendingIntent.getActivity(this, notifCount, i, PendingIntent.FLAG_ONE_SHOT);
        final int icon = R.mipmap.logo;
    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);

    Notification notification;
    notification = notificationBuilder.setSmallIcon(icon).setTicker(title)
            .setAutoCancel(true)
            .setContentTitle(title)
            .setContentText(body)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent)
            .setSmallIcon(R.mipmap.notification_icon)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), icon))
            .build();


    notificationBuilder.setContentTitle(title);
    notificationBuilder.setContentText(body);
    notificationBuilder.setAutoCancel(true);
    notificationBuilder.setSound(defaultSoundUri);
    notificationBuilder.setContentIntent(pendingIntent);
    notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(getResources(), icon));
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        notificationBuilder.setSmallIcon(R.mipmap.logo);
    } else {
        notificationBuilder.setSmallIcon(R.mipmap.logo);
    }

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(notifCount, notification);

}

This question is 2 years old. But is still relevant. This is how you could do it with the firebase console (without `click_action).

When your app is in background onMessageReceived will not be called. But when you get a notification while your app is in background, you will get an Intent along with the custom data you specify in the firebase console.

So when the user taps the notification the intent will then be executed to open your launcher activity. You can check for the data by getIntent().hasExtra("key") in your launcher activity. Where the "key" is whatever key you specify in the console.

Check if you have that "key" then, you can make another Intent and call startActivity

Here is an implementation of mine,

On my SplashActivity > OnCreate (This method Looks best if you have a splash screen as the launcher activity):

if (getIntent().hasExtra("key")){

      Intent intent = new Intent(this, TargetActivity.class);
      startActivity(intent);
      finish();

} else {
      startActivity(new Intent(this, MainActivity.class));
      finish();
}

This will just start the TargetActivity. You can add any functionality to this as per your wish :)

I also have the trouble like u but i don't get any right answer that is the facts i know,

  1. onNewIntent

this override method is not working when the app is background coz of working default action is android.intent.action.MAIN

  1. Firebase Console

firebase console is not enough power to handle click_action that means click action can't not reach to application when app in background.

  1. CURL

Curl is working in app background but not foreground may be i can't find.

curl --header "Authorization: key=<Colud_Messaging_Server_Key_here>" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  -d "{\"to\":\"dwdfosu6SDs:APA91bFWxZZB2f8AOgP9MG504cy5AhFECHGbYFfIzVixoAfy-ErT0NYQrREg150CbKYBtk3Ywpu7WQuWsQhk-VmoOe-0iDK3ZgaFZNvYxDuixZB8zQp0zydoXhyrMosi5C4eyBb7Ai1z\",\"notification\": {\"title\": \"Click Action Message\",\"text\": \"Sample message\",\"click_action\":\"noti\",\"ticket_download\":\"noti\"}}"

Add Minifest

<activity
   android:name=".activity.TicketDownload"
   android:exported="true">
   <intent-filter>
      <action android:name="noti" />
      <category android:name="android.intent.category.DEFAULT" />
   </intent-filter>
</activity>

note : cloud_messaging_server_key is locate setting>cloudmessaging

if anything new facts pls let's me know.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!