Intereting Posts
Потоковая передача с помощью Android MediaPlayer – уловки и буферизация Установка Android-приложения на устройство из Android Studio Сроки ожидания результата ClearAppData2 при запуске Xamarin UI Tests for Android Изменить направление ActionBar Реализовать анимацию падающего пальца на Google Maps android Удалить программную панель тени программно Android, как определить, что активность возвращается из другой активности? Жизненный цикл активности бок о бок Фрагменты. Нужно ли использовать обертыватель активности вокруг фрагмента, который включает всю активность? Применение setRotation к API карт v2 Файлы Jar в папке libs не используются в Android Gradle build Не найден ресурс, который соответствует указанному имени: attr 'android: keyboardNavigationCluster'. При обновлении до Support Library 26.0.0 Как добавить водяной знак в виджет Android EditText? Какая лучшая инфраструктура разработки мобильных веб-приложений Что именно делает команда «Исправить свойства проекта»?

Firebase onMessageReceived не вызывается, когда приложение в фоновом режиме

Я работаю с Firebase и тестирую отправку уведомлений в свое приложение с моего сервера, пока приложение находится в фоновом режиме. Уведомление отправляется успешно, оно даже появляется в центре уведомлений устройства, но когда появляется уведомление или даже если я нажимаю на него, метод onMessageReceived внутри моего FCMessagingService никогда не вызывается.

Когда я тестировал это, когда мое приложение находилось на переднем плане, вызывается метод onMessageReceived, и все работает нормально. Проблема возникает, когда приложение работает в фоновом режиме.

Является ли это предполагаемым поведением, или я могу это исправить?

Вот мой FBMessagingService:

import android.util.Log; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; public class FBMessagingService extends FirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage remoteMessage) { Log.i("PVL", "MESSAGE RECEIVED!!"); if (remoteMessage.getNotification().getBody() != null) { Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody()); } else { Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message")); } } } 

Solutions Collecting From Web of "Firebase onMessageReceived не вызывается, когда приложение в фоновом режиме"

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

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

Когда намерение запущено, вы можете использовать

 getIntent().getExtras(); 

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

Подробнее о сообщении уведомления см. В документах .

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

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

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

Таким образом, вы можете получать свои данные в onMessageReceived (сообщение RemoteMessage), как это …. позвольте сказать, что мне нужно получить идентификатор

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

У меня такая же проблема. Легче использовать «сообщение данных» вместо «уведомления». Сообщение данных всегда загружает класс onMessageReceived.

В этом классе вы можете сделать свое собственное уведомление с помощью сборщика уведомлений.

Пример:

  @Override public void onMessageReceived(RemoteMessage remoteMessage) { sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body")); } private void sendNotification(String messageTitle,String messageBody) { Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT); long[] pattern = {500,500,500,500,500}; Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_stat_name) .setContentTitle(messageTitle) .setContentText(messageBody) .setAutoCancel(true) .setVibrate(pattern) .setLights(Color.BLUE,1,1) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); } 

У меня есть идеальное решение для этого:

Вам необходимо выполнить два простых шага:

  1. Обновите свою firebase до компиляции версии com.google.firebase:firebase-messaging:10.2.1
  2. Переопределите handleIntent(Intent intent) в классе FirebaseMessagingService .

handleIntent() вызывается каждый раз, является ли приложение на переднем плане, фоновом или убитом состоянии.

В соответствии с документацией Firebase Cloud Messaging. Если «Активность» находится на переднем плане, тогда будет вызван вызовMessageReceived. Если «Активность» находится в фоновом режиме или закрыта, в центре уведомлений отображается уведомление о запуске активности запуска приложения. Вы можете вызвать свою настраиваемую активность при клике уведомления, если ваше приложение находится в фоновом режиме, вызвав службу обслуживания api для обмена сообщениями firebase как:

URL-адрес https://fcm.googleapis.com/fcm/send

Тип метода – POST

 Header- Content-Type:application/json Authorization:key=your api key 

Тело / Payload:

 { "notification": { "title": "Your Title", "text": "Your Text", "click_action": "OPEN_ACTIVITY_1" // should match to your intent filter }, "data": { "keyname": "any value " //you can get this data as extras in your activity and this data is optional }, "to" : "to_id(firebase refreshedToken)" } 

И с этим в вашем приложении вы можете добавить ниже код в свою деятельность для вызова:

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

Вот более понятные понятия о сообщении о битве. Я нашел его в своей команде поддержки.

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

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

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

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

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

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

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

 if(getIntent().getExtras()! = null){ //do your stuff }else{ //do that you normally do } 

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

Чтобы отправить эти пользовательские данные с изображением, вы можете использовать инструмент AdvancedREST Client , это расширение chrome и отправить сообщение со следующими параметрами:

 Rest client tool Link: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo 

Используйте этот url:- https://fcm.googleapis.com/fcm/send Content-Type:application/json Authorization:key=Your Server key From or 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.

И эта часть кода android-кода // будет содержать Push-сообщение

 String message = remoteMessage.getData().get("message1"); //imageUri will contain URL of the image to be displayed with Notification String imageUri = remoteMessage.getData().get("image"); //If the key AnotherActivity has value as True then when the user taps on notification, in the app AnotherActivity will be opened. //If the key AnotherActivity has value as False then when the user taps on notification, in the app MainActivity2 will be opened. String TrueOrFlase = remoteMessage.getData().get("AnotherActivity"); //To get a Bitmap image from the URL received bitmap = getBitmapfromUrl(imageUri); sendNotification(message, bitmap, TrueOrFlase); 

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

У меня была такая же проблема, и я сделал еще кое-что. Когда приложение находится в фоновом режиме, в системном трее отправляется уведомление, НО сообщение данных отправляется в onMessageReceived()
См. https://firebase.google.com/docs/cloud-messaging/downstream#monitor-token-generation_3.
И https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java

Чтобы обеспечить отправку сообщения, документы говорят: « Используйте свой сервер приложений и API-интерфейс FCM: установите только ключ данных. Может быть либо разборным, либо несовместимым ».
См. https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages.

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

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

Это упоминается (но не так подчеркнуто в документации FCM) здесь:

https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

Используйте сервер приложений и API-интерфейс FCM. Задайте только ключ данных . Может быть либо разборным, либо нескладным.

Просто назовите это в методе onCreate вашего MainActivity:

 if (getIntent().getExtras() != null) { // Call your NotificationActivity here.. Intent intent = new Intent(MainActivity.this, NotificationActivity.class); startActivity(intent); } 

Если приложение находится в фоновом режиме или неактивно (убито), и вы нажимаете « Уведомление» , вы должны проверить полезную нагрузку в LaunchScreen (в моем случае стартовый экран – MainActivity.java).

Итак, в MainActivity.java на onCreate check for Extras :

  if (getIntent().getExtras() != null) { for (String key : getIntent().getExtras().keySet()) { Object value = getIntent().getExtras().get(key); Log.d("MainActivity: ", "Key: " + key + " Value: " + value); } } 

Если ваша проблема связана с отображением Big Image, т.е. если вы отправляете push-уведомление с изображением из консоли firebase, и оно отображает изображение, только если приложение на переднем плане. Решение этой проблемы – отправить push-сообщение только с полем данных. Что-то вроде этого:

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

Бэкэнд, с которым я работаю, использует сообщения Notification, а не сообщения данных. Поэтому, прочитав все ответы, я попытался извлечь дополнительные данные из набора намерений, которые приходят к запущенной деятельности. Но независимо от того, какие ключи я пытался извлечь из getIntent().getExtras(); , Значение всегда было нулевым.

Тем не менее, я наконец нашел способ отправить данные с помощью сообщений Notification и извлечь их из намерения.

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

Пример:

 { "data": { "message": "message_body", "title": "message_title" }, "notification": { "body": "test body", "title": "test title" }, "to": "E4An.." } 

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

intent.getExtras().getString("title") будет message_title

И intent.getExtras().getString("message") будет message_body

Справка