Як обробляти сповіщення, коли програма у фоновому режимі у Firebase


426

Ось мій маніфест

    <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 є у вашому маніфесті? Я отримую помилку класу не знайдено .. і ніде не знайшов, що це перша частина параметра.
Едер Роша Безерра

Відповіді:


660

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 :)
Даніель С.

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-пристроях. Провели години, думаючи, що це актуальне питання, але потім виявилося нічого. Тому моя порада - протестувати його на різних пристроях. Я навіть перевірив його на VM, і я отримав сповіщення, навіть коли додаток було вбито. Я просто говорю це, щоб заощадити чийсь час.
Тарек-Дев

158

Щоб зробити бібліотеку firebase, щоб зателефонувати на ваш onMessageReceived () у наступних випадках

  1. Додаток на передньому плані
  2. Додаток у фоновому режимі
  3. Додаток було вбито

ви не повинні ставити ключ JSON "сповіщення" у своєму запиті до API бази файлів, а натомість використовувати "дані", див. нижче.

Наступне повідомлення не дзвонить вашій програмі 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, наприклад, завиток або листоноша (хромований плагін), api-повідомлення для обміну повідомленнями firebase, зверніться до документа тут - firebase.google.com/docs / хмара-повідомлення / http-server-ref
Teerakiat Chitawattanarat

1
це те, що я шукав більше дня ..... Дякую тобі, це прекрасно працювало. і було б краще, якщо ви поясніть, як ключові пари валей в даних можна обробляти в onMessageReceived (), щоб розпочати діяльність з цими значеннями.
Boopathi T

25
Ваш метод прекрасно працює, коли програма знаходиться у фоновому режимі, однак, коли програма вбита, я не отримую даних
Sanzhar

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. Отримайте інформацію "даних" із сповіщення в 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
Це має бути правильна відповідь. Жоден із документів нічого не говорить про те, що для того, щоб сповіщення навіть з’явилося в лотку, вимагає запуску кліків І Фільтр намірів. Вони обоє потрібні.
airowe

@airowe їм не потрібно, щоб повідомлення
з’являлося

У мене є і блоки даних, і повідомлення, але я не в змозі отримувати дані під час діяльності?
Ашвані

3
Я просто не розумію, як це не прийнята відповідь. Без запуску кліків це просто не вийде. Врятував мій день
Арун Шанкар

4
Дякуємо за вашу підтримку @ArunShankar На прийняту відповідь відповіли за 7 місяців до моєї, і це хороша відповідь. Я не можу зрозуміти, чому ніхто не говорить про керування кліками і саме тому я додав свою відповідь. Я дуже радий, що це дуже корисно для багатьох людей, і саме це важливо в кінці дня :)
Даніель С.

42

Відповідно до документації firebase при надсиланні нижче за течією за допомогою 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"
       }
}

Це корисне навантаження сповіщень використовується, коли ви бажаєте автоматично відображати сповіщення на системному треї, коли ваша програма знаходиться у фоновому режимі. Щоб отримати дані сповіщень, коли ваш додаток у фоновому режимі, вам слід додати натискання всередині корисного навантаження сповіщення .

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

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

Помістіть цей фільтр намірів у свій маніфест всередині одного з тегів активності. Коли ви натиснете сповіщення, він відкриє додаток і перейде безпосередньо до діяльності, яку ви визначаєте у керуванні кліками, у цьому випадку "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 не показують, куди рухається клавіша управління.
Джош

це не правильна відповідь? що таке дія кліку n, куди воно йде? хтось повинен проголосувати чи прибрати це
rana

1
@KyryloZapylaiev Я просто виправляю та оновлюю відповідь: "Помістіть цей фільтр намірів на свій маніфест всередині одного з ваших тегів активності".
Діка

1
@Josh оновлено та відформатовано. ви можете перевірити ще раз
Діка

32

Згідно з док

Обробляйте повідомлення у фоновому додатку

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

Сюди входять повідомлення, що містять як сповіщення, так і корисне навантаження даних. У цих випадках повідомлення надходить у системний трей приладу, а корисне навантаження даних надсилається в додатках наміру вашої запускової діяльності.

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

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

Редагувати:

На основі цієї теми :

Неможливо встановити корисну навантаження за допомогою кліку за допомогою 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\"}}"

1
ти правий. я читав документи. але я заплутався, куди це помістити у своєму маніфесті? я повинен запустити код на onMessageReceived на цьому файлі Java, щоб для цього що мені потрібно було робити, сер?
Parth Patel

Ви не можете змусити програму автоматично зателефонувати onMessageReveiced, коли він знаходиться на тлі. Натомість вам потрібно обробити отриманий намір і змусити обробника його зателефонувати. Або, мабуть, найкраще реалізувати окремий клас / метод, який викликається як onMessageReveiced, так і вашим наміром. Я додав обробник до onNewIntent основної діяльності, і він працює добре для мене.
діду

занадто пізно відповідати на питання @Parath Patel, але, можливо, це допоможе комусь іншим із тими ж проблемами, погляньте на мою відповідь тут stackoverflow.com/a/42279260/2734021
Даніель С.

куди довелося вчинити цю дію? для моєї діяльності або служби Firebasemessage?
Махді

** при багаторазовому переадресації повідомлень не працює? Наприклад: якщо у мене є три сповіщення від fcm на фоні, використовуючи "clickgery", перше повідомлення успішно переспрямоване, а потім 2 сповіщення натисніть, щоб перенаправлення активності не працює
prasanthMurugan

24

Працює з липня 2019 року

Android compileSdkVersion 28, buildToolsVersion 28.0.3 та обмін повідомленнями firebase: 19.0.1

Після багатогодинного дослідження всіх інших запитань та відповідей StackOverflow та спробу незліченних застарілих рішень, це рішення вдалося показати сповіщення у цих трьох сценаріях:

- Додаток на передньому плані:
повідомлення отримується методом onMessageReceived в моєму класі MyFirebaseMessagingService

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

- Додаток перебуває у фоновому режимі: повідомлення надсилається FCM в лоток сповіщень автоматично. Коли користувач торкається сповіщення, додаток виводиться на перший план, запускаючи активність, яка має в маніфесті android.intent.category.LAUNCHER. Оскільки в моєму додатку запускається запускMMM = "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 Notification Channel = default_channel_id Спеціальний ключ даних: значення заголовка: (той самий текст тут, ніж у полі заголовка розділу Повідомлення) ключ: значення тіла: (той самий текст тут, ніж у полі Повідомлення в розділі Повідомлення) ключ: значення керування клацанням: .MainActivity Sound = Інвалід
закінчується = 4 тижні

Ви можете налагодити його в Емуляторі за допомогою API 28 із Google Play.

Щасливого кодування!


2
Дякую за цю чудову відповідь.
Олексій Ченгалан

@alvaro, Якщо я хочу відкрити Url, коли отримую сповіщення, як я можу впоратися з цим
engmms

не працює в телефоні
Android Developer

Я не пробував телефон Vivo, але в даний час він працює в багатьох інших телефонах Android. Будь ласка, читайте повільно кожен крок, перевіряйте всі подробиці, а потім увімкніть налагоджувальні точки переключення в першому рядку кожного з методів, про які я тут згадував, підключіть реальний телефон до комп'ютера розвитку за допомогою кабелю та налагоджуйте додаток під час надсилання повідомлення від FCM. Переконайтеся, що ви надсилаєте повідомлення FCM з усіма параметрами та форматом, який я згадав. Удачі!
Alvaro

2
Це найсучасніша відповідь, оскільки документація Firebase тепер говорить: Коли ваша програма знаходиться у фоновому режимі, Android спрямовує повідомлення сповіщень у системний трей. Натискання користувачем сповіщення за замовчуванням відкриває запуск програми. Сюди входять повідомлення, що містять як сповіщення, так і корисне навантаження даних. У цих випадках повідомлення надходить у системний трей приладу, а корисне навантаження даних надсилається в додатках наміру вашої запускової діяльності. ( firebase.google.com/docs/cloud-messaging/android/… ) Стільки старих відповідей застаріли
Riot

20

Оскільки повідомлення, display-messagesщо надсилаються з Firefox Firefox, працює лише в тому випадку, якщо ваша програма стоїть на передньому плані. Тому data-messagesщо необхідно здійснити дзвінок на пошту до FCM

Кроки

  1. Встановіть розширене розширене клієнтське розширення Google Chrome введіть тут опис зображення

  2. Додайте наступні заголовки

    Ключ : Тип вмісту, значення : application / json

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

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

20

Щоб захопити повідомлення у фоновому режимі, вам потрібно скористатись a 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>

7
Це дійсно отримує повідомлення-сповіщення, коли програма знаходиться у фоновому режимі. Але це не зупиняє приймач Firebase за замовчуванням обробляти його, тому повідомлення все ще відображається як попередження про сповіщення.
Галя

На даний момент це не працює, тому я пропоную це рішення. На базі даних google є подана помилка. Ви можете перевірити це.
Ромулано

Чи можете ви опублікувати посилання на помилку тут
Галя

як отримати дані з повідомлення?
Раві Вагела

Це, очевидно, не працює, коли програма вбита. Я намагався це рішення годинами. чомусь приймач працює, поки програма знаходиться у фоновому режимі, а не працює, коли програма вбита
XcodeNOOB

16
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}

не викликається кожен раз, коли він викликається лише тоді, коли додаток знаходиться у приземленому просторі

є один метод переосмислення. Цей метод викликається кожен раз, незалежно від того, яка програма знаходиться на передньому плані, у фоновому режимі або вбита, але цей метод доступний у цій версії 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") 


}

з попереднім FirePi api цього методу не було, тому в цьому випадку пожежна база обробляє себе, коли додаток перебуває у фоновому режимі .... тепер у вас є цей метод, що коли-небудь ви хочете зробити ... u можете це зробити тут, у цьому методі .. ...

якщо ви використовуєте попередню версію, то за замовчуванням розпочнеться діяльність, і тоді ви можете отримати дані так само

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": "......."
    }
}

це залежить від того, як ти хочеш надати цей ключ даних або ти хочеш надіслати сповіщення все, що ти можеш дати ....... що ти коли-небудь дасть тут із тим самим ключем u, отримає ці дані ........ .

Є кілька випадків, коли ур не надсилає дії натискання в тому випадку, коли ви будете натискати на активацію за замовчуванням, буде відкрито, але якщо ви хочете відкрити свою конкретну діяльність, коли програма знаходиться у фоновому режимі, ви можете зателефонувати на вашу активність із цього методу handleIntent, оскільки це називається кожен раз


Я оновив обмін повідомленнями firebase до 10.2.1, додав дані до повідомлення повідомлень, і воно спрацювало. Передній план, фон та вбиті. Спасибі
Фірас Шруру

у Котліні я отримую цю помилку: (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"
   }
}

Немає необхідності використовувати функцію клацання. Потрібно просто отримати exras від намірів щодо роботи 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 . Не забудьте заповнити спеціальні поля даних у розділі Додаткові параметри


13

Ось більш чіткі поняття про повідомлення Firebase. Я знайшов це у їхньої групи підтримки.

Firebase має три типи повідомлень :

Повідомлення повідомлень : Повідомлення повідомлень працює на тлі або на передньому плані. Коли програма перебуває у фоновому режимі, повідомлення-повідомлення надходять у системний трей. Якщо додаток на першому плані, повідомлення обробляються onMessageReceived()або didReceiveRemoteNotificationзворотні дзвінки. Це, по суті, те, що називають дисплейними повідомленнями.

Інформаційні повідомлення : На платформі Android повідомлення даних може працювати на тлі та на передньому плані. Повідомлення даних буде оброблятися onMessageReceived (). Примітка, що стосується певної платформи, була б такою: На Android, корисне навантаження даних можна отримати в Намір, який використовується для запуску вашої діяльності. Щоб уточнити, якщо у вас є "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
    }
}

у цьому блоці шукайте свої ключі відповідно до інтерфейсу firebase.

У цьому прикладі мій ключ і значення, як вище; (вибачте за мову =)) введіть тут опис зображення

Коли мій код працює, я отримую "com.rda.note".

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

за допомогою цього рядка коду я закрив свою програму та відкрив Google Play Market

щасливе кодування =)


6

Я з'ясував сценарії,

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

А коли програма перебуває у фоновому режимі , викликається перша активність .

Тепер, якщо ви використовуєте сплеск-активність , тоді потрібно пам’ятати, що виклик буде плюскою , інакше якщо немає splashActivity, тоді, як би не було першої діяльності, буде називатися.

Потім вам потрібно перевірити getIntent () з firstActivity , щоб побачити , якщо він має якийсь - або згорток .if все в порядку , ви побачите розшаруванням там зі значеннями заповненими. Якщо значення тега даних пересилається з сервера виглядає наступним чином ,

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

Тоді в першій діяльності ви побачите, є дійсний намір ( getIntent () не є нульовим ), дійсний пакет і всередині пакета, буде весь згаданий вище 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 Sanaullah

1
привіт @AndroidSanaullah, ти можеш пояснити першу частину коду сервера, куди його насправді поставити, я зіткнувся з тією ж проблемою, але я не зовсім розумію серверну частину, ти використовуєш листоношу?
Шид

curl використовується для запиту, і всі параметри передаються йому. @ Shid
Android Sanaullah

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

Найпростіший спосіб надсилання повідомлень, навіть якщо програма перебуває у фоновому режимі та на передньому плані:

Інструмент для відпочинку клієнта: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

скористайтеся цією URL-адресою: - https://fcm.googleapis.com/fcm/send Тип вмісту: application / json Authorization: key = Ваш серверний ключ від або ключ авторизації (див. нижче посилання)

{ "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 і натиснувши кнопку «Повноваження» у меню зліва для вашого проекту. Серед перерахованих ключів API ключ сервера буде вашим ключем авторизації.

І вам потрібно помістити tokenID приймача в розділ «до» вашого запиту POST, надісланого за допомогою API.


2

ви хочете працювати надMessageReceived (RemoteMessage remoteMessage) у фоновому режимі, надішліть лише частину повідомлень про частину даних:

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

"AnotherActivity": "True", "to": "id пристрою або маркер пристрою"

Цим onMessageRecivied є фоном виклику та переднього плану, не потрібно обробляти сповіщення, використовуючи лоток сповіщень про активність запуску. Використовуйте це:

  public void onMessageReceived(RemoteMessage remoteMessage)
    if (remoteMessage.getData().size() > 0) 
    Log.d(TAG, "Message data payload: " + remoteMessage.getData());      

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.

у вас є джерело, це безпечно?
Yogesh Rathi

Це безпечно, я використовую його в своїх додатках. Однак 6 місяців з моменту публікації я не можу згадати джерело - я думаю, це документація на базу даних.
Джефф

1

Відповідно до OAUTH 2.0:

Виникне проблема Auth для цього випадку, оскільки FCM тепер використовує OAUTH 2

Тому я читаю документацію на базу даних, і згідно з документацією, новий спосіб розміщення повідомлення про це;

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

Заголовки

Key: Content-Type, Value: application/json

Авт

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

Тепер я можу використовувати цей маркер у своєму запиті на пошту. Потім я розміщую моє повідомлення, і тепер це обробляється моїми програмами на функціїMessageReceived.


Приймається відповідь працює, об'їдали токен аутентифікації не так, то потрібно прочитати , щоб спробувати його з Листоноша: stackoverflow.com/questions/45309674 / ...
Карлос Ісус Arancibia Taborga

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" />

Тепер для обробки повідомлень сповіщень у фоновому додатку слід визначити наміри у своїй першій діяльності, навіть якщо це 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 Notification" не додано ключ "data" та об'єкт . Таким чином, ви не отримаєте детального push-повідомлення, коли App перебуває у фоновому режимі чи вбито.

У цьому випадку вам потрібно вибрати консоль адміністратора заднього кінця для тестування фонового сценарію програми.

Тут ви додасте клавішу "data" до вашого набору. тому детальний поштовх буде показаний, як очікувалося. Сподіваюсь, це мало кому допомагає.


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, і він працює, коли додаток перебуває у фоновому, передньому плані чи вбитому стані.

Потрібно використовувати Сповіщення даних для обробки сповіщень, коли програма знаходиться у фоновому режимі.


-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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.