it-roy-ru.com

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

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

    <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]
311
Parth Patel

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

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

  1. Отображать сообщения: эти сообщения запускают обратный вызов onMessageReceived(), только когда ваше приложение находится в foreground
  2. Data Messages: Эти сообщения инициируют обратный вызов onMessageReceived()даже, если ваше приложение находится в foreground/background/kill

Команда Firebase не разработала пользовательский интерфейс для отправки data-messages на ваши устройства, но .

2. Как?

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

POSThttps://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
}
526
Antonio

Чтобы сделать библиотеку 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
    */
}
127
Teerakiat Chitawattanarat

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

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

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

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

74
Daniel S.

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

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

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

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

Если вы хотите открыть свое приложение и выполнить определенное действие, установите 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\"}}"
31
Shubhank

Согласно документации firebase в отправка вниз по течению с использованием firebase , есть 2 типа полезной нагрузки:

  1. данные

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

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

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

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

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

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

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

Эта полезная нагрузка messages используется, когда вы хотите автоматически отображать уведомление в системном трее, когда ваше приложение находится в фоновом режиме Чтобы получать данные уведомлений, когда ваше приложение в фоновом режиме, вы должны добавить 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"
   }
}
25
Hendy Evan

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

Шаги

  1. Установите расширение для расширенного клиентского доступа Google Chrome enter image description here

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

    Key: Content-Type, Value: application/json

    Ключ: авторизация, Значение: ключ = "ключ вашего сервера" enter image description here

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

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

public class FirebaseDataReceiver extends WakefulBroadcastReceiver {

    private final String TAG = "FirebaseDataReceiver";

    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "I'm in!!!");
        Bundle dataBundle = intent.getBundleExtra("data");
        Log.d(TAG, dataBundle.toString());
    }
}

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

<receiver
      Android:name="MY_PACKAGE_NAME.FirebaseDataReceiver"
      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>
15
Romulano
@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, поскольку вызывается каждый раз 

15
Avinash Jadaun

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

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

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

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

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

Нет необходимости использовать click_action. Вы должны просто получить 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 . Не забудьте заполнить пользовательские поля данных в разделе «Дополнительные параметры»

9
Mihuilk

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

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

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

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

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

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

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

9
Md. Sajedul Karim

2017 обновленный ответ

Вот четкий ответ из документов относительно этого:

 enter image description here

8
pulp_fiction

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

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

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

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

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

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

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

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

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


            }
        }
6
Shamsul Arefin Sajib

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

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

    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.

В этом примере мой ключ и значение, как указано выше; (извините за язык =))  enter image description here

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

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

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

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

6
Arda

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

<?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());
}
}
3
Android Sanaullah

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

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

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

{ "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
Syed Danish Haider

Удалить полезные данные уведомлений полностью из запроса вашего сервера. Отправлять только данные и обрабатывать их в 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
Zohab Ali

вы хотите работать с 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, «Полезные данные сообщения:» + remoteMessage.getData ()); 

1
user3385125

Июнь 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.
1
Jeff Padgett

Обновленный ответ в соответствии с OAUTH 2.0:  

Принятый ответ больше не работает (Ошибка 401) .. В этом случае возникнет проблема с аутентификацией, поскольку 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.

0
Ozan

С 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
Mohammad Mirzakhani

С помощью этого кода вы можете получить уведомление в фоновом режиме/на переднем плане, а также поместить действие:

//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
    }
0
Ashish Kumar

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

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

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

0
Max Droid