Intereting Posts

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

Справка