Консоль 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. Что мне нужно написать в этих полях, чтобы открыть "BasicNotificationActivity"?

Консоль Firebase

3 ответа

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

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

ОБНОВИТЬ:
Чтобы уточнить его ответ:

Добавить вспомогательный класс (или реализовать 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);
    }
}

В launcher-активности вашего приложения вызовите метод для проверки любых новых намерений в 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 года. Но все еще актуально. Вот как вы могли бы сделать это с помощью консоли 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, Вы можете добавить любую функциональность к этому согласно вашему желанию:)

Я использовал 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);

}

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

  1. onNewIntent

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

  1. Консоль Firebase

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

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

примечание: cloud_messaging_server_key - это параметр locate>cloudmessaging

если что-нибудь новые факты, пожалуйста, дайте мне знать.

Другие вопросы по тегам