Firebase可扩展通知:当应用在后台时显示图片

43

我正在Android中实现FCM通知,但是通知在应用程序状态(后台与前台)下有什么不同?

查看通知图片

我正在使用Postman和FCM API发送通知,以下是通知结构:

{ "notification": {
      "title": "Notification title",
      "body": "Notification message",
      "sound": "default",
      "color": "#53c4bc",
      "click_action": "MY_BOOK",
      "icon": "ic_launcher"
   },
   "data": {
       "main_picture": "URL_OF_THE_IMAGE"  
   },
   "to" : "USER_FCM_TOKEN"
}

要渲染的图像来自 data.main_picture

我实现了自己的FirebaseMessagingService,使得通知在前台状态下完美显示。通知代码如下:

NotificationCompat.BigPictureStyle notiStyle = new NotificationCompat.BigPictureStyle();
notiStyle.setSummaryText(messageBody);
notiStyle.bigPicture(picture);

Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setLargeIcon(bigIcon)
            .setContentTitle(title)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent)
            .setStyle(notiStyle); code here

NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());

然而,实际上服务并没有被执行。在AndroidManifest.xml中,Firebase服务如下声明:

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

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

我的问题不是LargeIconSmallIcon,而是显示大图。

感谢您的支持。


13
你找到解决方法了吗?我也在寻找同样的东西。 - Anirudh
你解决了这个问题吗? - SOBIR N
15个回答

24

12
只有当应用程序在前台时,才会调用onMessageReceived(message)方法。 - Anirudh
17
在后台中,onMessageReceived(message) 方法没有被调用。 - Parth Anjaria
5
你们所有人的部分观点都是正确的。当我使用 Firebase 控制台发送消息时,我也遇到了完全相同的问题。当应用程序在后台或被杀死时,onMessageReceived 不会被调用。但是,当我使用 API 发送时,onMessageReceived 总是会被调用。我下载了 Chrome 的高级 REST 客户端并开始发送通知数据。每次都会调用 onMessageReceived。感谢下面这篇教程:http://androidbash.com/firebase-push-notification-android/ - Krishan
3
是的,@Krishan说得对。一旦你找对了地方,文档就很清楚了。当FCM消息包含“notification”有效负载且应用程序在后台运行时,onMessageReceived不会被调用。如果它包含一个“data”有效载荷,则被调用,即使它在后台运行(在它被杀死或未运行的情况下,应用程序会启动,然后调用onMessageReceived)。这里是官方解释(这应该包含在答案中): https://firebase.google.com/docs/cloud-messaging/android/receive - Milos Ivanovic
2
请查看以下文章,了解后台图像通知的相关信息 https://sureshsala.blogspot.in/2018/01/firebase-push-notification-with-image.html - Suresh
显示剩余2条评论

15

如果有人在2019年看到这个内容,你可以简单地向通知对象中添加一个图像字段:

    {
        notification: {
            title: title,
            body: body,
            image: "http://path_to_image"
        },
        data: {
            click_action: "FLUTTER_NOTIFICATION_CLICK",
            your_data: ...,
        },
        token: token
    }

我已使用Flutter在Android上进行了测试,我想它在原生Android上应该也能工作,因为它们都可能使用相同的本机SDK。


使用 node-gcm 作为后端和 Ionic 5 作为前端,这对我不起作用。 - afe

7
如果您的问题与显示大图像有关,例如如果您从Firebase控制台发送带有图像的推送通知,并且只有在应用程序处于前台时才显示该图像。解决此问题的方法是仅发送数据字段的推送消息。
{ "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" }

这绝对解决了问题。


只有当应用程序在前台时,才会调用onMessageReceived(message)。那么当应用程序在后台时,仅发送数据字段将如何工作? - Mayura Devani
@MayuraDevani 我没有阅读 Firebase 的内部文件,但我已经测试过了,如果只发送数据字段,它可以正常工作,甚至自定义意图也可以正常工作。 - Arun
在我的情况下,如果我只使用数据字段,则只有当应用程序在前台时才会收到推送消息,而在后台或关闭时则不会。 - Mayura Devani
@MayuraDevani,您需要更改FirebaseMessagingService中的代码,其中会检查应用程序是否在前台运行,请将其删除。同样的代码将适用于所有情况。 顺便问一下,使用Firebase控制台发送通知时是否有通知? - Arun
是的,在从Firebase控制台发送时,会收到通知。嘿,如果应用程序被杀死,你的代码是否能正常工作?我的意思是,如果你强制停止应用程序,然后发送通知,它能正常工作吗? - Mayura Devani
显示剩余4条评论

5

包含通知和数据负载的消息(例如使用Postman发送的示例),由FCM库自动显示在终端用户设备上。这不包括(大)图片。

我猜有两种可能性:

  1. Try what Rashmi Jain suggested. However, this solution could work right now and stop working tomorrow, if the Firebase library is updated (and thus the implementation of the message handling)

  2. Send a data message with Postman. You may not fill the notification object in the JSON therefore, so it could look something like this:

    {
      "message": {
        "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
        "data":{    
          "title" : "Awesome title",
          "body"  : "Your awesome push notification body",
          "image"  : "your_image_url"
        }
      }
    }
    
我会选第二个选项。祝好运!

什么是Post URL? - Satish Gupta

4

更新于2019年8月。

[浪费了几天时间,只因为py不支持通知的最新更改]

只需将image = url添加到您的通知对象中即可。

在本机Android中有效。只需将image添加到通知对象中。还请注意,Python库中不存在图像字段。[截至8月19日]https://github.com/firebase/firebase-admin-python

我使用了PHP和这个库https://github.com/kreait/firebase-php/ 它非常简单易用,最重要的是,在应用程序在后台或已被关闭时,它可以用于发送大型图像通知。

代码:

<?php

require __DIR__.'/vendor/autoload.php';
require __DIR__.'/simple_html_dom.php';

use Kreait\Firebase;
use Kreait\Firebase\ServiceAccount;
use Kreait\Firebase\Messaging\Notification;
use Kreait\Firebase\Messaging\CloudMessage;

$serviceAccount = ServiceAccount::fromJsonFile('/path/to/cred.json');

$firebase = (new Firebase\Factory())->withServiceAccount($serviceAccount)->create();
$messaging = $firebase->getMessaging();

// this works when app is closed or in bg
$notification = Notification::fromArray([
    'title' => $title,
    'body' => $body,
    'image' => $imageUrl,
]);

// for foreground process 
$data = [
    'image' => $imageUrl,
    'news_id' => $news_id,
];

$topic = 'default_topic1';

$message = CloudMessage::withTarget('topic', $topic)
    ->withNotification($notification) // optional
    ->withData($data);

$messaging->send($message);

print_r($message);

3
如果您正在发送推送通知,则请在数据中获取所有必需的内容,而不是在通知中获取,例如:
{
   "data": {
       "main_picture": "URL_OF_THE_IMAGE",
       "title": "Notification title",
      "click_action": "MY_BOOK", 
      "color": "#53c4bc", 
   },
   "to" : "USER_FCM_TOKEN"
}

移除通知对象并从数据对象中获取所有值。

希望对您有所帮助。


1

推送通知包中需要有“Data”关键字。

除了以上回答之外,如果您正在使用FCM控制台测试推送通知,则“data”关键字和对象不会被添加到推送通知包中。因此,当应用程序在后台或已关闭时,您将无法接收详细的推送通知。

在这种情况下,您必须选择后端管理控制台来测试应用程序后台场景。

在这里,您将向您的推送包中添加“data”关键字。因此,详细的推送通知将如预期一样显示。

希望这对您有所帮助。


1
我通过使用以下方法解决了这个问题:
{
  "to": "dllBLnfORt6Bnc3hg:APA91bGz7reSbPs-vlgy9fX-gkGRZ5zdUfFB0k9b2UwvYFuEeHwyGywtpjWOQJcxGBq4bb32Uctbh2aR2SDdA8NWRjC6posTUq8WUCHFN_knRDvEfZhkSxsSgI1rbQTfYbUpuKq1kSH_",
  "notification": {
    "body": "Queen's Platinum Jubilee award recipients honoured",
    "OrganizationId": "2",
    "content_available": true,
    "priority": "high",
    "subtitle": "Elementary School",
    "title": "Platinum price incresed!",
    "image": "https://www.thenaturalsapphirecompany.com/education/wp-content/uploads/2017/12/pyrite-pyrites-mineral-sulfide-56030.jpeg"
  },
  "data": {
    "priority": "high",
    "sound": "app_sound.wav",
    "content_available": true,
    "bodyText": "xxxxxxxxxxxxx",
    "organization": "Catalytic Price",
    "type" : "asasf"
  }
}

notification下添加image键。
更多详情请访问以下网址: https://firebase.google.com/docs/cloud-messaging/android/send-image#rest

2023年唯一有效的答案 - Oush

1

如果在2021年您仍然遇到此问题,请将图像转换为位图,使用.setStyle而不是setLargeIcon(bitmap)。

val pendingIntent = PendingIntent.getActivity(this, 0, intent, FLAG_ONE_SHOT)
    val notification = NotificationCompat.Builder(this, Companion.CHANNEL_ID)
        .setContentTitle(message.data["title"])
        .setContentText(message.data["message"])
        .setStyle(NotificationCompat.BigPictureStyle().bigPicture(bitmap))
        .setSmallIcon(R.drawable.ic_home)
        .setAutoCancel(true)
        .setContentIntent(pendingIntent)
        .build()

0

推送完全取决于接收到的推送请求和设备功能,例如在某些设备上,电池寿命会影响我们传递的所有内容,只有URL图像而不是实际图像在推送请求中,因此设备必须具备下载图像的能力,而Android / APK必须显示图像,并且需要使用Firebase或APNS。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接