Как обрабатывать уведомления, когда приложение в фоновом режиме в Firebase

429

Вот мой манифест

    <service android:name=".fcm.PshycoFirebaseMessagingServices">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <service android:name=".fcm.PshycoFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

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

Вот мой onMessageReceivedкод Это вызывается, если мое приложение работает на переднем плане, а не когда приложение в фоновом режиме. Как запустить этот код, когда приложение тоже в фоновом режиме?

// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // If the application is in the foreground handle both data and notification messages here.
    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
    data = remoteMessage.getData();
    String title = remoteMessage.getNotification().getTitle();
    String message = remoteMessage.getNotification().getBody();
    String imageUrl = (String) data.get("image");
    String action = (String) data.get("action");
    Log.i(TAG, "onMessageReceived: title : "+title);
    Log.i(TAG, "onMessageReceived: message : "+message);
    Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
    Log.i(TAG, "onMessageReceived: action : "+action);

    if (imageUrl == null) {
        sendNotification(title,message,action);
    } else {
        new BigPictureNotification(this,title,message,imageUrl,action);
    }
}
// [END receive_message]
Парт Патель
источник
1
Это написано в примере переопределения onMessageReceived () , говорится во второй строке комментария Not getting messages here? See why this may be: goo.gl/39bRNJ . Решение, как и приведенные ниже ответы, можно найти в документации в Сообщениях с уведомлением и полезными данными
fllo
Короче говоря, чтобы разбудить ваше убитое приложение, вы всегда должны отправлять уведомление с объектом данных для вызова вашего обработчика класса обслуживания уведомлений FirebaseMessagingService.onMessageReceived () в вашем приложении. Также попробуйте отправить его не с консоли Firebase, а опубликовать откуда-то еще (например, онлайн-сервис почтового тестирования).
Зон
1
у меня это решение сработало stackoverflow.com/a/44150822/6632278 надеюсь поможет. Удачи
Тони Барахас
что ".fcm." PshycoFirebaseMessagingServices в вашем манифесте? Я получаю ошибку класса не найден .. и нигде не нашел, что это за первая часть параметра.
Эдер Роча Безерра

Ответы:

661

1. Почему это происходит?

В FCM (Firebase Cloud Messaging) есть два типа сообщений:

  1. Сообщения на дисплее : эти сообщения вызывают onMessageReceived()обратный вызов только тогда, когда ваше приложение находится на переднем плане
  2. Сообщения данных : эти сообщения запускают onMessageReceived()обратный вызов, даже если ваше приложение находится на переднем плане / в фоне / убито

ПРИМЕЧАНИЕ. Команда Firebase еще не разработала пользовательский интерфейс для отправки data-messagesна ваши устройства. Вы должны использовать свой сервер для отправки этого типа!



2. Как?

Для этого вам необходимо выполнить POSTзапрос по следующему URL:

POST https://fcm.googleapis.com/fcm/send

Заголовки

  • Ключ: Content-Type , Значение: application/json
  • Ключ: Authorization , Значение: key=<your-server-key>

Тело с использованием тем

{
    "to": "/topics/my_topic",
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     }
}

Или, если вы хотите отправить его на определенные устройства

{
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     },
    "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}


ПРИМЕЧАНИЕ. Убедитесь, что вы не добавляете ключ JSON. notification
ПРИМЕЧАНИЕ. Чтобы получить ключ сервера, его можно найти в консоли Firebase:Your project -> settings -> Project settings -> Cloud messaging -> Server Key

3. Как обрабатывать push-уведомления?

Вот как вы обрабатываете полученное сообщение:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String myCustomKey = data.get("my_custom_key");

     // Manage data
}
Антонио
источник
4
Вы можете отправить «данные» и «уведомления» ключи в том же уведомлении, следуя этим шагам stackoverflow.com/a/42279260/2734021 :)
Daniel S.
15
Firebase team have not developed a UI to send data-messages to your devices, yet.Изменилось ли это в прошлом году?
Hankrecords
2
@Antonio В oreo, когда приложение убито, onMessageReceived не вызывается. у меня просто полезная нагрузка только с данными. какое-нибудь обновление у вас есть?
Самир Мангролия
63
Когда приложение в фоновом режиме onMessageReceivedне вызывается, и это серьезная проблема в FCM !!! Также, пожалуйста, обновите свой ответ.
Мухаммед Бабар
2
Ну, для меня, кажется, это происходит на определенных устройствах Android. Потратил часы, думая, что это актуальная проблема, но потом ничего не получилось. Поэтому мой совет - протестировать его на разных устройствах. Я даже протестировал его на виртуальной машине, и я получил уведомление, даже когда приложение было убито. Я просто говорю это, чтобы сэкономить чье-то время.
Тарек-Дев
158

Чтобы сделать библиотеку firebase для вызова вашего onMessageReceived () в следующих случаях

  1. Приложение на переднем плане
  2. Приложение в фоновом режиме
  3. Приложение было убито

Вы не должны помещать ключ JSON «извещение» в свой запрос к API Firebase, а вместо этого использовать «данные», см. ниже.

Следующее сообщение не будет вызывать ваш onMessageReceived (), когда ваше приложение находится в фоновом режиме или убито, и вы не можете настроить свое уведомление.

{
   "to": "/topics/journal",
   "notification": {
   "title" : "title",
   "text": "data!",
   "icon": "ic_notification"
    }
}

но вместо этого будет работать

{
  "to": "/topics/dev_journal",
   "data": {
       "text":"text",
       "title":"",
       "line1":"Journal",
       "line2":"刊物"
   }
} 

По сути, сообщение отправляется в аргументе RemoteMessage вместе с вашим объектом данных как Map, тогда вы можете управлять уведомлением в onMessageReceived, как в фрагменте здесь.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();

     //you can get your text message here.
     String text= data.get("text");


     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        // optional, this is to make beautiful icon
             .setLargeIcon(BitmapFactory.decodeResource(
                                    getResources(), R.mipmap.ic_launcher))  
        .setSmallIcon(smallIcon)  //mandatory
      .......
    /*You can read more on notification here:
    https://developer.android.com/training/notify-user/build-notification.html
    https://www.youtube.com/watch?v=-iog_fmm6mE
    */
}
Тиракиат Читаваттанарат
источник
1
Возможно ли добиться этого с консоли Firebase?
Кодер
@koder, к сожалению, консоль Firebase не поддерживает это, вы должны использовать инструмент для отправки запроса на отправку сообщения в firebase, такого как curl или postman (плагин chrome), api для обмена сообщениями в firebase, пожалуйста, обратитесь к документу здесь - firebase.google.com/docs / cloud-messaging / http-server-ref
Teerakiat Chitawattanarat
1
это то, что я искал больше суток ..... Огромное спасибо, все сработало отлично. и было бы лучше, если бы вы объяснили, как пары ключей vale в данных могут обрабатываться в onMessageReceived (), чтобы начать действие с этими значениями.
Boopathi T
25
Ваш метод работает хорошо, когда приложение находится в фоновом режиме, однако, когда приложение убито, я не получаю данные
Санжар
8
Та же проблема Санжара. Если приложение убито, я не получаю никакого сообщения.
Джакомо М
104

Мне кажется, что все ответы неполные, но во всех них есть что-то, что вам нужно для обработки уведомления, содержащего данные, когда ваше приложение находится в фоновом режиме.

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

1. Добавьте фильтр намерений следующим образом:

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

к деятельности, которую вы хотите обработать данные уведомления.

  1. Отправлять уведомления в следующем формате:

    { 
     "notification" : {
            "click_action" : ".MainActivity", 
            "body" : "new Symulti update !", 
            "title" : "new Symulti update !", 
            "icon" : "ic_notif_symulti" }, 
     "data": { ... },
     "to" : "c9Vaa3ReGdk:APA91bH-AuXgg3lDN2WMcBrNhJZoFtYF9" }

Ключ здесь добавить

"click_action" : ".MainActivity"

где .MainActivity - это действие с фильтром намерений, добавленным на шаге 1.

  1. Получить информацию «data» из уведомления в onCreate «.MainActivity»:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //get notification data info
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
           //bundle must contain all info sent in "data" field of the notification
        }
    }

И это должно быть все, что вам нужно сделать. Надеюсь, это кому-нибудь поможет :)

Даниэль С.
источник
5
Это должен быть правильный ответ. Ни один из документов ничего не говорит о требовании click_action И фильтра намерений, чтобы уведомление даже отображалось в трее. Они оба необходимы.
Airowe
@airowe, они не требуются для отображения уведомления
AlwaysConfused
У меня есть блоки данных и уведомлений, но я не могу получать данные в действии?
Ашвани
3
Я просто не понимаю, как это не принятый ответ. Без click_action это просто не будет работать. Спас мой день
Арун Шанкар
4
Спасибо за вашу поддержку @ArunShankar. Принятый ответ был дан за 7 месяцев до моего, и это хороший ответ. Я не могу понять, почему никто не говорит о click_action, и поэтому я добавил свой ответ. Я очень рад, что это очень полезно для многих людей, и это важно в конце дня :)
Даниэль С.
42

В соответствии с документацией по firebase в send downstream с использованием firebase , существует 2 типа полезной нагрузки:

  1. данные

    Этот параметр указывает пользовательские пары ключ-значение для полезной нагрузки сообщения. Клиентское приложение отвечает за обработку сообщений с данными. Сообщения данных имеют только пользовательские пары ключ-значение.

  2. уведомление

    Этот параметр указывает предопределенные видимые пользователем пары ключ-значение полезной нагрузки уведомления. FCM автоматически отображает сообщение для устройств конечного пользователя от имени клиентского приложения. Уведомительные сообщения имеют предопределенный набор видимых пользователю ключей.

Когда вы находитесь на переднем плане, вы можете получить данные внутри FCM, используя onMessageReceived () , вы можете получить свои данные из полезной нагрузки данных .

data = remoteMessage.getData();
String customData = (String) data.get("customData");

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

{
  "notification": {
        "title" : "title",
        "body"  : "body text",
        "icon"  : "ic_notification",
        "click_action" : "OPEN_ACTIVITY_1"
       }
}

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

Если вы хотите открыть свое приложение и выполнить определенное действие [в то время как в фоновом режиме], установите click_action в полезной нагрузке уведомления и сопоставьте его с фильтром намерений в Activity, которую вы хотите запустить. Например, установите для click_action значение OPEN_ACTIVITY_1, чтобы активировать фильтр намерений, как показано ниже:

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

Поместите этот фильтр намерений в свой манифест, внутри одного из тегов активности. Когда вы щелкнете по уведомлению, оно откроет приложение и сразу перейдет к активности, которую вы определили в click_action, в данном случае «OPEN_ACTIVTY_1». И внутри этой деятельности вы можете получить данные:

Bundle b = getIntent().getExtras();
String someData = b.getString("someData");

Я использую FCM для своего приложения для Android и использую обе полезные нагрузки. Вот пример JSON, который я использую:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification",
    "click_action" : "OPEN_ACTIVITY_1"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}
Хенди эван
источник
«Поместите этот намеренный фильтр в манифест внутри тега приложения». Вы не можете поместить интент-фильтр внутри тега приложения.
Кирилл Запылаев
ваши JSON не показывают, куда идет ключ click_action.
Джош
это не правильный ответ? что такое действие щелчка и куда оно идет? кто-то должен проголосовать вниз или убрать это
Рана
1
@KyryloZapylaiev Я просто исправляю и обновляю ответ: «Поместите этот фильтр намерений в свой манифест, внутри одного из тегов активности».
Дика
1
@ Джош обновлен и отформатирован. Вы можете проверить это снова
Дика
32

Согласно документам

Обрабатывать сообщения в фоновом приложении

Когда ваше приложение находится в фоновом режиме, Android направляет уведомления в системный трей. При нажатии на уведомление пользователя открывается панель запуска приложения по умолчанию.

Это включает в себя сообщения, которые содержат как уведомления, так и данные. В этих случаях уведомление доставляется в системный трей устройства, а полезная нагрузка данных доставляется в дополнениях к цели вашего средства запуска.

Если вы хотите открыть свое приложение и выполнить определенное действие, установите click_action в полезной нагрузке уведомления и сопоставьте его с фильтром намерений в Activity, которую вы хотите запустить. Например, установите для click_action значение OPEN_ACTIVITY_1, чтобы активировать фильтр намерений, как показано ниже:

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

Редактировать :

Основано на этой теме :

Вы не можете установить полезную нагрузку click_action с помощью Firebase Console. Вы можете попробовать протестировать с помощью команды curl или пользовательского http-сервера.

curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>" 
     --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  
     -d "{\"to\":\"/topics/news\",\"notification\": 
         {\"title\": \"Click Action Message\",\"text\": \"Sample message\",
            \"click_action\":\"OPEN_ACTIVITY_1\"}}"
Shubhank
источник
1
вы правы. Я прочитал документы. но я запутался, где поставить это в моем манифесте? я должен запустить код onMessageReceived для этого файла Java, так что для этого, что я должен сделать, сэр?
Парт Патель
Вы не можете заставить приложение автоматически вызывать onMessageReveiced, когда оно находится в фоновом режиме. Вместо этого вам нужно обработать полученное намерение и заставить обработчик вызвать его. Или, возможно, лучше всего реализовать отдельный класс / метод, который вызывается как onMessageReveiced, так и вашей обработкой намерений. Я добавил обработчик в onNewIntent основной деятельности, и он прекрасно работает для меня.
diidu
слишком поздно отвечать на вопросы @Parath Patel, но, может быть, это поможет кому-то еще с такими же проблемами, посмотрите мой ответ здесь stackoverflow.com/a/42279260/2734021
Даниэль С.
куда нужно было поставить это действие? для моей деятельности или службы Firebasemessage?
Махди
** при многократном перенаправлении уведомлений не работает? Например: если у меня есть три уведомления от fcm на фоне с использованием «click_action», первое уведомление успешно перенаправлено, а затем 2 уведомления щелкают, перенаправление активности не работает
prasanthMurugan
24

Работает с июля 2019 года

Android compileSdkVersion 28, buildToolsVersion 28.0.3 и Firebase-Messaging: 19.0.1

После многих часов исследований по всем остальным вопросам и ответам StackOverflow и пробования бесчисленных устаревших решений этому решению удалось отобразить уведомления в следующих 3 сценариях:

- Приложение находится на переднем плане:
уведомление получено методом onMessageReceived в моем классе MyFirebaseMessagingService

- Приложение было убито (оно не работает в фоновом режиме): уведомление отправляется на панель уведомлений автоматически с помощью FCM. Когда пользователь касается уведомления, приложение запускается путем вызова действия, в котором есть android.intent.category.LAUNCHER в манифесте. Вы можете получить часть данных уведомления, используя getIntent (). GetExtras () в методе onCreate ().

- Приложение в фоновом режиме: уведомление отправляется на панель уведомлений автоматически с помощью FCM. Когда пользователь касается уведомления, приложение выводится на передний план, запуская действие, в котором есть android.intent.category.LAUNCHER в манифесте. Поскольку мое приложение имеет launchMode = "singleTop" в этом действии, метод onCreate () не вызывается, потому что одно действие того же класса уже создано, вместо этого вызывается метод onNewIntent () этого класса, и вы получаете часть данных уведомление там с помощью intent.getExtras ().

Шаги: 1. Если вы определяете основную деятельность своего приложения следующим образом:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:screenOrientation="portrait"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name=".MainActivity" />
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

2 - добавьте эти строки в метод onCreate () вашего MainActivity.class

Intent i = getIntent();
Bundle extras = i.getExtras();
if (extras != null) {
    for (String key : extras.keySet()) {
        Object value = extras.get(key);
        Log.d(Application.APPTAG, "Extras received at onCreate:  Key: " + key + " Value: " + value);
    }
    String title = extras.getString("title");
    String message = extras.getString("body");
    if (message!=null && message.length()>0) {
        getIntent().removeExtra("body");
        showNotificationInADialog(title, message);
    }
}

и эти методы к тому же MainActivity.class:

@Override
public void onNewIntent(Intent intent){
    //called when a new intent for this class is created.
    // The main case is when the app was in background, a notification arrives to the tray, and the user touches the notification

    super.onNewIntent(intent);

    Log.d(Application.APPTAG, "onNewIntent - starting");
    Bundle extras = intent.getExtras();
    if (extras != null) {
        for (String key : extras.keySet()) {
            Object value = extras.get(key);
            Log.d(Application.APPTAG, "Extras received at onNewIntent:  Key: " + key + " Value: " + value);
        }
        String title = extras.getString("title");
        String message = extras.getString("body");
        if (message!=null && message.length()>0) {
            getIntent().removeExtra("body");
            showNotificationInADialog(title, message);
        }
    }
}


private void showNotificationInADialog(String title, String message) {

    // show a dialog with the provided title and message
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();
}

3- создайте класс MyFirebase следующим образом:

package com.yourcompany.app;

import android.content.Intent;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {


    public MyFirebaseMessagingService() {
        super();
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        Log.d(Application.APPTAG, "myFirebaseMessagingService - onMessageReceived - message: " + remoteMessage);

        Intent dialogIntent = new Intent(this, NotificationActivity.class);
        dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        dialogIntent.putExtra("msg", remoteMessage);
        startActivity(dialogIntent);

    }

}

4- создайте новый класс NotificationActivity.class следующим образом:

package com.yourcompany.app;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper;

import com.google.firebase.messaging.RemoteMessage;

public class NotificationActivity extends AppCompatActivity {

private Activity context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    Bundle extras = getIntent().getExtras();

    Log.d(Application.APPTAG, "NotificationActivity - onCreate - extras: " + extras);

    if (extras == null) {
        context.finish();
        return;
    }

    RemoteMessage msg = (RemoteMessage) extras.get("msg");

    if (msg == null) {
        context.finish();
        return;
    }

    RemoteMessage.Notification notification = msg.getNotification();

    if (notification == null) {
        context.finish();
        return;
    }

    String dialogMessage;
    try {
        dialogMessage = notification.getBody();
    } catch (Exception e){
        context.finish();
        return;
    }
    String dialogTitle = notification.getTitle();
    if (dialogTitle == null || dialogTitle.length() == 0) {
        dialogTitle = "";
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(context, R.style.myDialog));
    builder.setTitle(dialogTitle);
    builder.setMessage(dialogMessage);
    builder.setPositiveButton(getResources().getString(R.string.accept), new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();

}

}

5- Добавьте эти строки в манифест вашего приложения внутри тегов.

    <service
        android:name=".MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/>

    <activity android:name=".NotificationActivity"
        android:theme="@style/myDialog"> </activity>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/notification_icon"/>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/color_accent" />

6 - добавьте эти строки в методе Application.java onCreate () или в методе MainActivity.class onCreate ():

      // notifications channel creation
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      // Create channel to show notifications.
      String channelId = getResources().getString("default_channel_id");
      String channelName = getResources().getString("General announcements");
      NotificationManager notificationManager = getSystemService(NotificationManager.class);
      notificationManager.createNotificationChannel(new NotificationChannel(channelId,
              channelName, NotificationManager.IMPORTANCE_LOW));
  }

Выполнено.

Теперь, чтобы это хорошо работало в 3 упомянутых сценариях, вы должны отправить уведомление с веб-консоли Firebase следующим образом:

В разделе «Уведомление»: заголовок уведомления = заголовок, отображаемый в диалоговом окне уведомлений (необязательно). Текст уведомления = сообщение, отображаемое пользователю (обязательно). Затем в разделе «Цель»: приложение = приложение Android и в разделе «Дополнительные параметры»: канал уведомлений Android. = default_channel_id Ключ пользовательских данных: значение заголовка: (здесь тот же текст, что и в поле «Заголовок» раздела «Уведомления») ключ: значение тела: (здесь тот же текст, что и в поле «Сообщение» раздела «Уведомления») ключ: значение click_action: .MainActivity Sound = Отключено
Истекает = 4 недели

Вы можете отладить его в эмуляторе с API 28 в Google Play.

Удачного кодирования!

Alvaro
источник
2
Спасибо за этот отличный ответ.
Алекс Ченгалан
@alvaro, если я хочу открыть URL-адрес при получении уведомления, как я могу справиться с этим
engmms
не работает телефон vivo opp, когда приложение закрыто или убито
Android Developer
Я не пробовал в телефоне Vivo, но в настоящее время он работает во многих других телефонах Android. Пожалуйста, внимательно прочитайте каждый шаг, проверьте все детали, а затем включите отладку точек останова в первой строке каждого из методов, которые я упомянул здесь, подключите реальный телефон к компьютеру для разработки с помощью кабеля и отладьте приложение во время отправки сообщение от FCM. Убедитесь, что вы отправляете сообщения FCM со всеми параметрами и форматом, который я упомянул. Удачи!
Альваро
2
Это самый актуальный ответ, поскольку документация Firebase теперь гласит: Когда ваше приложение находится в фоновом режиме, Android направляет уведомления в системный трей. При нажатии на уведомление пользователя открывается панель запуска приложения по умолчанию. Это включает в себя сообщения, которые содержат как уведомления, так и данные. В этих случаях уведомление доставляется в системный трей устройства, а полезная нагрузка данных доставляется в дополнениях к цели вашего средства запуска. ( firebase.google.com/docs/cloud-messaging/android/… ) Так много старых ответов устарели
бунт идет вразнос
20

Так как те, display-messagesкоторые отправляются из Firebase Notification UI, работают, только если ваше приложение находится на переднем плане. Потому data-messagesчто есть необходимость сделать POST вызов FCM

меры

  1. Установите расширение для расширенного клиента Google Chrome Extension введите описание изображения здесь

  2. Добавьте следующие заголовки

    Ключ : Content-Type, Значение : application / json

    Ключ : Авторизация, Значение : ключ = "ключ вашего сервера" введите описание изображения здесь

  3. Добавить тело

    • При использовании тем:

      {
          "to" : "/topics/topic_name",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
          }
      }
    • При использовании регистрационного идентификатора:

      {
          "registration_ids" : "[{"id"},{id1}]",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
           }
      }

Это оно!. Теперь слушайте onMessageReceivedобратный звонок как обычно.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}
SkyNet
источник
20

Для захвата сообщения в фоновом режиме вам нужно использовать BroadcastReceiver

import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.legacy.content.WakefulBroadcastReceiver
import com.google.firebase.messaging.RemoteMessage

class FirebaseBroadcastReceiver : WakefulBroadcastReceiver() {

    val TAG: String = FirebaseBroadcastReceiver::class.java.simpleName

    override fun onReceive(context: Context, intent: Intent) {

        val dataBundle = intent.extras
        if (dataBundle != null)
            for (key in dataBundle.keySet()) {
                Log.d(TAG, "dataBundle: " + key + " : " + dataBundle.get(key))
            }
        val remoteMessage = RemoteMessage(dataBundle)
        }
    }

и добавьте это в свой манифест:

<receiver
      android:name="MY_PACKAGE_NAME.FirebaseBroadcastReceiver"
      android:exported="true"
      android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
</receiver>
Romulano
источник
7
Это действительно получает уведомление, когда приложение находится в фоновом режиме. Но это не мешает получателю Firebase по умолчанию обрабатывать его, поэтому сообщение по-прежнему отображается в виде уведомления.
Галя
На данный момент не работает, поэтому я и предлагаю это решение. Существует ошибка в базе данных Google. Вы можете проверить это.
Ромулано
Не могли бы вы опубликовать ссылку на ошибку здесь
Галя
как получить данные из уведомления?
Рави Вагела
Это явно не работает, когда приложение убито. Я пробовал это решение в течение нескольких часов. по какой-то причине приемник работает, когда приложение находится в фоновом режиме, и не работает, когда приложение убито
XcodeNOOB
16
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}

не вызывается каждый раз, когда вызывается только когда приложение находится в forground

есть один метод переопределения, этот метод вызывается каждый раз, независимо от того, какое приложение находится на переднем плане или в фоновом режиме или убито, но этот метод доступен с этой версией API Firebase

это версия, которую вы должны импортировать из Gradle

compile 'com.google.firebase:firebase-messaging:10.2.1'

это метод

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

    // you can get ur data here 
    //intent.getExtras().get("your_data_key") 


}

с предыдущим API Firebase этого метода не было, так что в этом случае сам обработчик базы огня, когда приложение находится в фоновом режиме .... теперь у вас есть этот метод, что когда-либо вы хотите ... вы можете сделать это здесь, в этом методе ... ...

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

if(getIntent().getExtras() != null && getIntent().getExtras().get("your_data_key") != null) {
String strNotificaiton = getIntent().getExtras().get("your_data_key").toString();

// делай что хочешь ....}

как правило, это структура с сервера, мы получаем в уведомлении

{
    "notification": {
        "body": "Cool offers. Get them before expiring!",
        "title": "Flat 80% discount",
        "icon": "appicon",
        "click_action": "activity name" //optional if required.....
    },
    "data": {
        "product_id": 11,
        "product_details": "details.....",
        "other_info": "......."
    }
}

это зависит от того, как вы хотите дать этот ключ данных или вы хотите дать уведомление обо всем, что вы можете дать ....... то, что когда-либо вы дадите здесь с тем же ключом, вы получите эти данные ........ ,

Есть несколько случаев, когда вы не отправляете действие клика в том случае, когда вы нажимаете на уведомление, откроется действие по умолчанию, но если вы хотите открыть свое конкретное действие, когда приложение находится в фоновом режиме, вы можете вызвать это действие с помощью метода handleIntent, потому что это вызывается каждый раз

Авинаш Джадаун
источник
Я обновил firebase-сообщения до 10.2.1, добавил данные к уведомлению, и это сработало. Передний план, Фон и Убит. Спасибо
Firas Shrourou
в Kotlin я получаю эту ошибку: (44, 5) 'handleIntent' в 'FirebaseMessagingService' является окончательным и не может быть переопределено
ugali soft
Он не работает над версиями firebase 11
venu46
14

По документам: 17 мая 2017 г.

Когда ваше приложение находится в фоновом режиме , Android направляет уведомления в системный трей. При нажатии на уведомление пользователя открывается панель запуска приложения по умолчанию .

Это включает в себя сообщения, которые содержат как уведомления, так и полезные данные (и все сообщения, отправленные из консоли уведомлений). В этих случаях уведомление доставляется в системный трей устройства, а полезная нагрузка данных доставляется в дополнениях к цели вашего средства запуска.

Итак, вы должны использовать оба уведомления полезных данных + данные:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

Нет необходимости использовать click_action. Вам просто нужно получить отрывки из намерений о деятельности LAUNCHER.

<activity android:name=".MainActivity">
        <intent-filter>
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>

Код Java должен быть в методе onCreate для MainActivity:

Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
    Bundle extras = intent.getExtras();
    String someData= extras.getString("someData");
    String someData2 = extras.getString("someData2");
}

Вы можете протестировать оба уведомления полезной нагрузки + данные из консоли уведомлений Firebase . Не забудьте заполнить пользовательские поля данных в разделе «Дополнительные параметры»

Mihuilk
источник
14

Вот более четкие понятия о сообщении Firebase. Я нашел это от их команды поддержки.

** Firebase имеет три типа сообщений **:

Уведомления : Уведомление работает на заднем или переднем плане. Когда приложение находится в фоновом режиме, уведомления уведомлений доставляются в системный трей. Если приложение находится на переднем плане, сообщения обрабатываются onMessageReceived()илиdidReceiveRemoteNotification обратными вызовами. По сути, это то, что называется отображением сообщений.

Сообщения данных : на платформе Android сообщение данных может работать как на заднем, так и на переднем плане. Сообщение данных будет обработано onMessageReceived (). Примечание для конкретной платформы будет следующим: На Android полезная нагрузка данных может быть получена в Intent, используемом для запуска вашей деятельности. Чтобы уточнить, если у вас есть "click_action":"launch_Activity_1", вы можете получить это намерение getIntent()только изActivity_1 .

Сообщения с полезными нагрузками как для уведомлений, так и для данных . В фоновом режиме приложения получают полезную нагрузку для уведомлений в области уведомлений и обрабатывают полезные данные только тогда, когда пользователь нажимает на уведомление. На переднем плане ваше приложение получает объект сообщения с обоими полезными нагрузками. Во-вторых,click_action параметр часто используется в полезных данных уведомлений, а не в полезных данных. Если этот параметр используется внутри полезных данных, этот параметр будет обрабатываться как настраиваемая пара ключ-значение, и поэтому вам нужно будет реализовать настраиваемую логику, чтобы он работал так, как задумано.

Кроме того, я рекомендую вам использовать onMessageReceivedметод (см. Сообщение данных) для извлечения пакета данных. Исходя из вашей логики, я проверил объект пакета и не нашел ожидаемого содержимого данных. Вот ссылка на похожий случай, который может дать больше ясности.

Для получения дополнительной информации посетите мою эту тему

Г-н Саджедул Карим
источник
8

Простое резюме, как это

  • если ваше приложение работает;

    onMessageReceived()

это триггеры.

  • если ваше приложение не запущено (убито смахиванием);

    onMessageReceived()

не запускается и не доставляется по адресу direclty. Если у вас есть специальная пара ключ-значение. Они не работают, потому что onMessageReceived () не работает.

Я нашел этот путь;

В своей деятельности по запуску вставьте эту логику,

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState, R.layout.activity_splash);

    if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("PACKAGE_NAME")) {

        // do what you want

        // and this for killing app if we dont want to start
        android.os.Process.killProcess(android.os.Process.myPid());

    } else {

        //continue to app
    }
}

в этом блоке if ищите ваши ключи в соответствии с пользовательским интерфейсом Firebase.

В этом примере мой ключ и значение как выше; (простите за язык =)) введите описание изображения здесь

Когда мой код работает, я получаю "com.rda.note".

android.os.Process.killProcess(android.os.Process.myPid());

с этой строкой кода я закрыл свое приложение и открыл Google Play Market

счастливого кодирования =)

Арда
источник
6

Я выяснил сценарии,

Когда приложение находится на переднем плане , метод onMessageReceived () вызывается из FirebaseService. Так что pendingIntent , определенный в классе обслуживания будет называться.

И когда приложение находится в фоновом режиме , вызывается первое действие .

Теперь, если вы используете всплывающее действие , то следует иметь в виду, что будет вызываться splashactivity , иначе, если не будет splashActivity, то будет вызываться то, чем является первое действие.

Затем вам нужно проверить getIntent () из firstActivity , чтобы увидеть , если он имеет какой - либо сверток .if все в порядке , вы увидите расслоением там со значениями заполненными. Если значение тэга данных пересылается с сервера выглядит следующим образом ,

"data": {
    "user_name": "arefin sajib",
    "value": "user name notification"
  }

Затем в первом упражнении вы увидите, что есть действительное намерение ( getIntent () не равно NULL ), допустимый пакет и внутренний пакет, там будет весь JSON, упомянутый выше, с данными в качестве ключа .

Для этого сценария код для извлечения значения будет выглядеть так:

    if(getIntent()!=null){
            Bundle bundle = getIntent().getExtras();
            if (bundle != null) {
                try {
                   JSONObject object = new JSONObject(bundle.getStringExtra("data"));
String user_name = object.optString("user_name");

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
        }
Шамсул Арефин Саджиб
источник
3

Спасибо всем вам за ваши ответы. Но я решил это, отправив сообщение с данными вместо отправки уведомления . Код сервера

<?php
$url = "https://fcm.googleapis.com/fcm/send";
$token = "C-l6T_a7HouUK****";
$serverKey = "AAAAaOcKS00:********";
define( 'API_ACCESS_KEY', $serverKey );
$registrationIds = array($token);
// prep the bundle

$msg = array

(
 'message'  => 'here is a message. message',
 'title'        => 'This is a title. title',
 'subtitle' => 'This is a subtitle. subtitle',
 'tickerText'   => 'Ticker text here...Ticker text here...Ticker text 
 here',
 'vibrate'  => 1,
 'sound'        => 1,
 'largeIcon'    => 'large_icon',
 'smallIcon'    => 'small_icon'

);

$fields = array

(
  'registration_ids'    => $registrationIds,
  'data'            => $msg

);
$headers = array

(
  'Authorization: key=' . API_ACCESS_KEY,
 'Content-Type: application/json'

);


$ch = curl_init();

curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' 
);

curl_setopt( $ch,CURLOPT_POST, true );

curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );

curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );

curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );

curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );

$result = curl_exec($ch );

curl_close( $ch );

echo $result;

?>

И поймал данные в onMessageReceived

public class MyFirebaseMessagingService extends FirebaseMessagingService     {

  private static final String TAG = "MyFirebaseMsgService";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

      sendNotification(remoteMessage.getData().get("message"));
     }
   // Check if message contains a notification payload.
    else if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    sendNotification(remoteMessage.getNotification().getBody());
    }


}
   private void sendNotification(String messageBody) {
    Intent intent = new Intent(this, Notify.class).putExtra("msg",messageBody);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    String channelId = "idddd";
    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(MyFirebaseMessagingService.this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("FCM Message")
                    .setContentText(messageBody)
                    .setAutoCancel(true)
                    .setSound(defaultSoundUri)
                    .setContentIntent(pendingIntent);

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
Андроид Санаулла
источник
1
это также работает с фоном?
Табиш хан
@Tabishkhan Да, брат, он работает, если у вас есть какие-либо вопросы, не стесняйтесь спрашивать меня .. спасибо
Android
1
Привет @AndroidSanaullah, можете ли вы объяснить первую часть кода сервера, где вы на самом деле поместили его, я сталкиваюсь с той же проблемой, но я не совсем понимаю серверную часть, вы используете почтальон?
Шид
curl используется для запроса, и все параметры передаются ему. @ Shid
Android
2

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

Вот что я отправляю с сервера:

{
  "data":{
    "id": 1,
    "missedRequests": 5
    "addAnyDataHere": 123
  },
  "to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......"
}

Таким образом, вы можете получить ваши данные onMessageReceived(RemoteMessage message)следующим образом: (скажем, я должен получить идентификатор)

Object obj = message.getData().get("id");
        if (obj != null) {
            int id = Integer.valueOf(obj.toString());
        }

И так же вы можете получить любые данные, которые вы отправили с сервера в пределах onMessageReceived().

Зохаб Али
источник
2

Простой способ отправки сообщений, даже если приложение находится в фоновом режиме и на переднем плане, как описано ниже: - Чтобы отправить сообщение с помощью API, вы можете использовать инструмент под названием AdvancedREST Client, расширение chrome, и отправить сообщение со следующими параметрами.

Инструмент для отдыха клиентов Ссылка: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

используйте этот URL: - https://fcm.googleapis.com/fcm/send Тип контента: application / json Авторизация: ключ = ключ вашего сервера от или ключ авторизации (см. ниже ссылка)

{ "data": {
    "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg",
    "message": "Firebase Push Message Using API"
    "AnotherActivity": "True"
     },
  "to" : "device id Or Device token"
}

Ключ авторизации можно получить, посетив консоль разработчиков Google и нажав кнопку Credentials в левом меню вашего проекта. Среди перечисленных ключей API ключом авторизации будет ключ сервера.

И вам нужно поместить tokenID получателя в раздел «to» вашего POST-запроса, отправленного с помощью API.

Сайед Датский Хайдер
источник
2

вы хотите работать с onMessageReceived (RemoteMessage remoteMessage) в фоновом режиме и отправлять только часть данных, уведомляющую эту часть:

"data":    "image": "",    "message": "Firebase Push Message Using API", 

"AnotherActivity": "True", "to": "идентификатор устройства или токен устройства"

При этом onMessageRecivied является фоном вызова и передним планом, нет необходимости обрабатывать уведомления с помощью панели уведомлений о вашей активности запуска. Обработайте данные, используя это:

  public void onMessageReceived(RemoteMessage remoteMessage)
    if (remoteMessage.getData().size() > 0) 
    Log.d(TAG, "Message data payload: " + remoteMessage.getData());      
user3385125
источник
1

Июнь 2018 г. Ответ -

Вы должны убедиться, что в сообщении нет ни одного ключевого слова «уведомления». Включите только «данные», и приложение сможет обработать сообщение в onMessageReceived, даже если оно находится в фоновом режиме или уничтожено.

Использование облачных функций:

const message = {
    token: token_id,   // obtain device token id by querying data in firebase
    data: {
       title: "my_custom_title",
       body:  "my_custom_body_message"
       }
    }


return admin.messaging().send(message).then(response => {
    // handle response
});

Затем в вашем onMessageReceived (), в вашем классе, расширяющем com.google.firebase.messaging.FirebaseMessagingService:

if (data != null) {
  Log.d(TAG, "data title is: " + data.get("title");
  Log.d(TAG, "data body is: " + data.get("body");
}

// build notification using the body, title, and whatever else you want.
Джефф Паджетт
источник
у вас есть источник, это безопасно?
Йогеш Рати
Это безопасно, я использую это в своих приложениях. Тем не менее, через 6 месяцев после публикации я не могу вспомнить источник - я предполагаю, что это документация Firebase.
Джефф Паджетт
1

Согласно OAUTH 2.0:

В этом случае будет проблема с аутентификацией, потому что теперь FCM использует OAUTH 2

Итак, я прочитал документацию FireBase и, согласно документации, новый способ публикации сообщения данных;

POST: https://fcm.googleapis.com/v1/projects/YOUR_FIREBASEDB_ID/messages:send

Заголовки

Key: Content-Type, Value: application/json

Auth

Bearer YOUR_TOKEN 

Пример тела

{
   "message":{
    "topic" : "xxx",
    "data" : {
         "body" : "This is a Firebase Cloud Messaging Topic Message!",
         "title" : "FCM Message"
          }
      }
 }

В URL есть идентификатор базы данных, который вы можете найти в консоли Firebase. (Идут проектные расчеты)

А теперь давайте возьмем наш токен (он будет действителен только 1 час):

Сначала в консоли Firebase откройте « Настройки»> «Учетные записи служб» . Нажмите Создать новый закрытый ключ , надежно сохраните файл JSON, содержащий ключ. Мне был нужен этот файл JSON для авторизации запросов к серверу вручную. Я скачал это.

Затем я создаю проект node.js и использую эту функцию для получения моего токена;

var PROJECT_ID = 'YOUR_PROJECT_ID';
var HOST = 'fcm.googleapis.com';
var PATH = '/v1/projects/' + PROJECT_ID + '/messages:send';
var MESSAGING_SCOPE = 'https://www.googleapis.com/auth/firebase.messaging';
var SCOPES = [MESSAGING_SCOPE];

  router.get('/', function(req, res, next) {
      res.render('index', { title: 'Express' });
      getAccessToken().then(function(accessToken) {
        console.log("TOKEN: "+accessToken)
      })

    });

function getAccessToken() {
return new Promise(function(resolve, reject) {
    var key = require('./YOUR_DOWNLOADED_JSON_FILE.json');
    var jwtClient = new google.auth.JWT(
        key.client_email,
        null,
        key.private_key,
        SCOPES,
        null
    );
    jwtClient.authorize(function(err, tokens) {
        if (err) {
            reject(err);
            return;
        }
        resolve(tokens.access_token);
    });
});
}

Теперь я могу использовать этот токен в своем почтовом запросе. Затем я публикую свое сообщение с данными, и теперь оно обрабатывается функцией приложения onMessageReceived.

Озан
источник
Принятый ответ работает, аутентификация с пустым токеном - не тот путь, вам нужно прочитать это, чтобы попробовать это с почтальоном: stackoverflow.com/questions/45309674/…
Карлос Хесус Арансибия
1

С 2019 года Google Firebase сильно изменил свои API, я имею в виду: 'com.google.firebase:firebase-messaging:18.0.0'

в 18.0.0 они удалены, MyFirebaseInstanceIDServiceи вам нужно получить токен, MyFirebaseMessagingServiceтак что вам просто нужно написать:

@Override
public void onNewToken(String token) {
    Log.d(TAG, "Refreshed token: " + token);

}

а также в вашем AndroidManifest.xml вы должны удалить:

<service android:name=".service.MyFirebaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>

Также рекомендуется установить значения по умолчанию, чтобы настроить внешний вид уведомлений. Вы можете указать пользовательский значок по умолчанию и пользовательский цвет по умолчанию, которые применяются, когда эквивалентные значения не установлены в полезной нагрузке уведомления.

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

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_notification" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/push_channel" />

Теперь для обработки уведомительных сообщений в фоновом приложении вы должны определить Intent в своей первой Деятельности, даже если это SplashScreen. Когда ваше приложение находится в фоновом режиме, Android направляет уведомления в системный трей. При нажатии на уведомление пользователя открывается панель запуска приложения по умолчанию.

например, если ваш Json такой:

 "data": {
"message": "2",
"title": "1",
"pushType" : "banner",
"bannerLink": "http://www.google.com",
"image" : "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"}

вам просто нужно написать простое намерение получить эти значения:

        Bundle extras = intent.getExtras();
        String bannerLink = extras.getString("bannerLink");
        ...
        String channelId = extras.getString("channelId");
Мухаммед Мирзахани
источник
0

В дополнение к ответам выше, если вы тестируете push-уведомления с помощью консоли FCM , ключ и объект «данные» не добавляются в комплект Push-уведомлений. Таким образом, вы не получите детальное push-уведомление, когда приложение находится в фоновом режиме или убито.

В этом случае вы должны выбрать консоль администратора для тестирования фонового сценария приложения.

Здесь вы добавите ключ «data» в ваш push-пакет. Таким образом, подробный толчок будет показан, как и ожидалось. Надеюсь, это поможет немногим.

Макс Дроид
источник
0

Используя этот код, вы можете получить уведомление в фоновом режиме / на переднем плане, а также поместить действие:

//Data should come in this format from the notification
{
  "to": "/xyz/Notifications",
  "data": {
      "key1": "title notification",
      "key2": "description notification"
  }
}

В приложении используйте этот код:

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
      String key1Data = remoteMessage.getData().get("key1");
      // use key1Data to according to your need
    }
Ашиш Кумар
источник
// Данные должны поступать в этом формате из уведомления {"to": "/ xyz / Notifications", "data": {"key1": "уведомление о заголовке", "key2": "уведомление об уведомлении"}} Как писать этот код в php сервисе?
Табиш хан
-3

Там будет два типа уведомлений

  1. Отображать уведомления - отображаются только уведомления, только приложение не открыто и находится в стеке приложений.
  2. Уведомление о данных - обратный вызов переходит в метод onMessageReceived службы firebasemessagingservice, и он работает, когда приложение находится в фоновом, переднем или завершенном состоянии.

Вы должны использовать Data Notifications для обработки уведомлений, когда приложение находится в фоновом режиме.

abhi.nalavade
источник
-5

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

* библиотека https://github.com/erdalceylan/com-google-firebase-messaging

 dependencies {
        compile 'com.google.firebase:firebase-core:11.2.0'
        compile 'com.github.erdalceylan:com-google-firebase-messaging:v1-11.2.0'
    }

*

@WorkerThread
public void onMessageReceived(RemoteMessage var1) {
  //your app is in background or foreground all time calling
}

надежда помогает Удачи

Эрдал Цейлан
источник
2
Бесполезный
2
Это ужасное предложение.
vsecades