You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android后台时Firebase推送自定义配置失效问题

为什么Firebase推送在应用后台时不使用代码中的自定义配置,仅读取Manifest默认设置?

这个问题的核心是Firebase Cloud Messaging(FCM)的两种消息类型处理逻辑不同,我给你详细拆解清楚:

问题根源:FCM消息类型的差异

FCM推送分为两种核心消息类型,它们在应用后台时的处理逻辑完全不一样:

  • 通知消息(Notification Messages):这种消息包含notification字段,当应用处于后台时,系统会直接接管通知的展示,不会触发你的onMessageReceived()方法。这时候你代码里写的角标、分组、自定义PendingIntent等配置根本不会被执行,只能使用Manifest里配置的默认图标、颜色等参数,也就是你遇到的情况。
  • 数据消息(Data Messages):这种消息只包含data字段,不管应用是前台还是后台,都会触发onMessageReceived(),所有通知的展示逻辑完全由你的代码控制,这时候你的自定义配置(角标、分组等)就能正常生效。

看你的代码就能发现:你只在remoteMessage.getNotification() != null时才调用sendNotification(),也就是只处理了前台时的通知消息;而后台时通知消息被系统直接展示,你的代码根本没机会执行,自然自定义配置不生效。

解决办法

方案一:只发送数据消息(推荐)

让你的后端推送时只发送数据消息(不要包含notification字段,所有参数都放在data里),这样不管应用在前台还是后台,都会走到你的onMessageReceived()方法,你可以完全自定义通知的所有属性。

比如后端的推送请求体应该是这样的:

{
  "to": "目标设备的FCM Token",
  "data": {
    "title": "你的推送标题",
    "body": "你的推送内容",
    "link": "https://example.com",
    "badge": "1"
  }
}

然后修改你的onMessageReceived()方法,优先从data中获取所有参数,确保不管消息类型是什么,都能触发自定义通知逻辑:

@Override 
public void onMessageReceived(RemoteMessage remoteMessage) { 
    String badge = "0"; 
    Uri uri = Uri.parse(getString(R.string.app_host_name)); 
    String title = "";
    String body = "";

    // 优先从data字段获取所有推送参数
    Map<String, String> data = remoteMessage.getData(); 
    if (data.size() > 0) { 
        try { 
            uri = Uri.parse(data.get("link")); 
            badge = data.get("badge");
            title = data.get("title");
            body = data.get("body");
        } catch (NullPointerException e) { 
            // 处理空指针异常,比如给默认值
        } 
    }

    // 兼容旧的推送格式:如果data里没有标题内容,再尝试从notification字段取
    if (TextUtils.isEmpty(title) && remoteMessage.getNotification() != null) {
        RemoteMessage.Notification notification = remoteMessage.getNotification();
        title = notification.getTitle();
        body = notification.getBody();
    }

    // 确保标题和内容不为空时发送自定义通知
    if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(body)) {
        sendNotification(title, body, uri.toString(), badge); 
    }
}

方案二:通知消息+数据字段组合(不推荐后台场景)

如果必须保留notification字段,后台时系统还是会自动展示通知,但你可以在data里携带额外参数,在用户点击通知后,通过启动的MainActivity来处理角标更新等逻辑。不过这种方式无法在后台时控制通知的展示样式(比如分组、角标显示),因为通知已经被系统创建了,所以更推荐方案一。

内容的提问来源于stack exchange,提问作者Littlebobbydroptables

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:35:20