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

FirebaseMessagingService子类未调用onMessageReceived的FCM通知处理问题

解决FCM自定义MessagingService无效及数据提取失败问题

先来说说你最困惑的核心问题:自定义的FirebaseMessagingService子类看似完全不起作用——能正常收通知但改不了内容,删掉代码功能不受影响,断点调试和Log输出也没反应。这大概率是消息类型不匹配或者服务配置有疏漏导致的,咱们一步步排查:

一、自定义MessagingService无效的原因及解决

  1. 区分FCM的两种消息类型
    FCM推送分两种核心类型:

    • 通知消息(Notification Message):带notification字段的推送,FCM SDK会直接在系统托盘显示通知,不会触发onMessageReceived方法。这就解释了为什么你删代码还能收通知——因为根本没走你的自定义逻辑!
    • 数据消息(Data Message):只有data字段的推送,或者App处于前台状态时的通知消息,才会进入onMessageReceived,这时候你的自定义代码才会生效。

    你可以检查下推送的payload,如果是从Firebase控制台发送的,默认是通知消息,要切换到「自定义数据」模式发数据消息,或者同时包含notification和data字段。

  2. 验证Manifest中的服务配置
    确保你的自定义服务在Manifest里声明正确,没有拼写错误,也没有重复声明默认服务:

    <service
        android:name=".YourCustomMessagingService" <!-- 替换成你的子类全路径 -->
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

    另外要确认包名com.e...和推送目标包名完全一致,控制台填错包名也会导致服务无法触发。

  3. 检查Gradle依赖版本
    确保firebase-messaging的依赖版本和其他Firebase组件版本匹配,避免版本冲突导致服务无法注册:

    implementation 'com.google.firebase:firebase-messaging:23.4.0' <!-- 建议使用最新稳定版 -->
    

二、提取推送内容中的数字作为Intent Extra失败的解决

搞清楚上面的问题后,提取数字的逻辑才能正常执行。这里给你一套可行的方案:

  1. 确保能拿到推送数据
    如果是数据消息,在onMessageReceived里通过remoteMessage.getData()获取所有字段:

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // 获取推送的产品名称,比如"Nike45"
        String productName = remoteMessage.getData().get("product_name");
        if (productName == null) return;
    
        // 提取数字部分
        String productId = extractNumbers(productName);
        if (productId == null) return;
    
        // 构建Intent并传入Extra参数
        Intent intent = new Intent(this, TargetActivity.class);
        intent.putExtra("PRODUCT_ID", productId);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    
        // 创建PendingIntent,用于点击通知跳转
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
    
        // 自定义通知并显示
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "CHANNEL_ID")
                .setContentTitle("自定义通知标题")
                .setContentText(productName)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentIntent(pendingIntent)
                .setAutoCancel(true);
    
        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        notificationManager.notify(1, builder.build());
    }
    
    // 提取字符串中的数字
    private String extractNumbers(String input) {
        // 用正则匹配所有连续数字
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(input);
        if (matcher.find()) {
            return matcher.group();
        }
        return null;
    }
    
  2. 后台点击通知获取Extra的注意事项
    如果推送同时包含notification和data字段,App后台时系统会自动显示通知,点击通知跳转后,data字段会附加到启动的Activity的Intent中。你需要在目标Activity的onCreate或onNewIntent中获取:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_target);
    
        // 获取Extra参数
        String productId = getIntent().getStringExtra("PRODUCT_ID");
        if (productId != null) {
            // 执行你的业务逻辑
        }
    }
    

    注意:如果Activity的启动模式是standard,每次点击通知都会创建新实例,建议设置为singleTop或singleTask,避免重复创建,同时在onNewIntent中更新Intent数据。

最后总结几个关键检查点

  • 先确认推送的消息类型,只有数据消息或前台状态下的通知消息才会触发自定义服务
  • 核对Manifest中的服务声明和包名是否完全匹配
  • 用正则表达式确保能准确提取字符串中的数字
  • 测试时优先用数据消息,这样能直接验证onMessageReceived中的逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:40:01