Консоль Firebase: как указать click_action для уведомлений

Я применил Firebase и тестировал уведомления Firebase. Когда приложение находится на переднем плане, у меня нет проблем, я реализовал службу, которая расширяет FirebaseMessagingService и обрабатывает сообщение и данные в onMessageReceived

У меня проблемы, когда приложение находится в фоновом режиме, я хотел бы отправить уведомление, которое открывает конкретное действие и выполняет то, что я планирую делать, а не только открытие приложения.

Я сделал, как описано в руководстве Firebase, но я не могу запустить конкретную операцию.

Здесь манифест:

<activity android:name=".BasicNotificationActivity">
            <intent-filter>
                <action android:name="OPEN_ACTIVITY_1" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

И вот Firebase Console. Что мне нужно написать в этих полях, чтобы открыть мою "BasicNotificationActivity"?

Консоль Firebase

Ответ 1

Это дубликат этого вопроса: Уведомление Firebase FCM о загрузке click_action

Но ответ, который был принят автором этого вопроса, просто утверждает, что это невозможно с Firebase Console, но это - с легким обходным решением. Этот ответ by diidu на тот же вопрос объясняет обходной путь, который я использовал бы.

UPDATE:
Чтобы уточнить его ответ:

Добавить класс-помощник (или реализовать метод startActivity() как-то):

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);
    }
}

В активности запуска вашего приложения вызовите mehtod, чтобы проверить любые новые намерения в onCreate() и onNewIntent() (onNewIntent() вызывается вместо onCreate(), если действие запущено с одним верхним флагом)

@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);
       }
}

И в 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);
     }
 }

Чтобы отправить уведомление с помощью консоли firebase, поместите пару ключ-значение как пользовательские данные следующим образом:

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

Теперь, когда уведомление получено и будет нажато, оно откроет вашу активность. Если ваше приложение находится на переднем плане, оно также сразу же изменится на активность - возможно, было бы хорошо спросить пользователя, хочет ли он перейти к этой операции или нет (путем отображения диалога в onMessageReceived()).

Ответ 2

Я использовал метод handleIntent(Intent intent) для обработки intent и переместился на этот конкретный экран. Ниже мой код работает отлично, даже когда приложение находится в фоновом режиме:

FCMMessagingService.java, который 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);

}

Ответ 3

У меня также есть проблемы, такие как u, но я не получаю никакого правильного ответа это факты, которые я знаю,

  • onNewIntent

этот метод переопределения не работает, когда приложение является фоном для рабочего действия по умолчанию: android.intent.action.MAIN

  1. Firebase Console

firebase console недостаточно для обработки click_action, что означает, что действие нажатия не может попасть в приложение, когда приложение находится в фоновом режиме.

  1. CURL

Curl работает в фоновом режиме приложения, но не на переднем плане, я не могу найти.

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\"}}"

Добавить файл "Минифест"

<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 - это установка местоположения > облачная реклама

если что-нибудь новое сообщит мне факты.

Ответ 4

Этому вопросу 2 года. Но все еще актуально. Вот как вы могли бы сделать это с помощью консоли Firebase (без 'click_action).

Когда ваше приложение находится в фоновом режиме, onMessageReceived не будет вызываться. Но когда вы получаете уведомление, когда ваше приложение находится в фоновом режиме, вы получите Intent вместе с пользовательскими данными, которые вы указываете в консоли Firebase.

Таким образом, когда пользователь нажимает на уведомление, тогда будет выполнено the intent, чтобы открыть вашу активность запуска. Вы можете проверить данные с помощью getIntent().hasExtra("key") в вашей активности запуска. Где "key" - это любой ключ, указанный вами в консоли.

Проверьте, есть ли у вас этот "key" тогда вы можете сделать другое Intent и вызвать startActivity

Вот моя реализация,

На мой SplashActivity > OnCreate (этот метод выглядит лучше, если у вас есть заставка в качестве действия запуска):

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

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

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

Это только запустит TargetActivity. Вы можете добавить любую функциональность к этому согласно вашему желанию :)