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

Android应用前台运行时点击接收的FCM通知无响应问题求助

问题根因

  1. FCM推送的前后台处理逻辑存在差异:应用后台时,通知由FCM系统自动弹出,点击事件由Capacitor推送插件接管,所以你编写的pushNotificationActionPerformed回调可以正常触发,跳转逻辑生效。
  2. 应用前台时,你在原生层的onMessageReceived方法里自行构建通知弹出,这里的PendingIntent仅配置了跳转首页,既没有携带推送参数也没有和JS层的回调打通;同时原生层直接拦截了推送事件,没有抛给Capacitor插件,所以JS层的pushNotificationReceived收不到事件,点击通知自然也不会触发你写的跳转逻辑。
  3. 你原有代码里PendingIntent使用了0作为flag,Android 12及以上系统要求PendingIntent必须明确指定FLAG_IMMUTABLE或FLAG_MUTABLE,否则会被系统判定为无效,这也是点击通知无响应的直接原因之一。

解决方法

方案一:保留原生层通知弹出逻辑,补全配置

修改onMessageReceived代码如下:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    Log.d("msg", "onMessageReceived: " + remoteMessage.getData().get("message"));
    Intent intent = new Intent(this, MainActivity.class);
    // 把推送全量数据塞入Intent传递到页面
    if (remoteMessage.getData() != null) {
        for (Map.Entry<String, String> entry : remoteMessage.getData().entrySet()) {
            intent.putExtra(entry.getKey(), entry.getValue());
        }
    }
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    // 适配高版本Android的PendingIntent强制flag要求
    int pendingFlag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0;
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, pendingFlag);
    String channelId = "Default";
    NotificationCompat.Builder builder = new  NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(remoteMessage.getNotification().getTitle())
            .setContentText(remoteMessage.getNotification().getBody())
            .setAutoCancel(true)
            .setContentIntent(pendingIntent);
    NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(channelId, "Default channel", NotificationManager.IMPORTANCE_DEFAULT);
        manager.createNotificationChannel(channel);
    }
    // 通知ID用时间戳避免新通知覆盖旧通知
    int notifyId = (int) System.currentTimeMillis();
    manager.notify(notifyId, builder.build());
}

同时在MainActivity中补充onNewIntent方法,接收通知传入的参数,传递给JS层执行跳转逻辑即可:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
    // 此处判断如果是通知点击进入,将参数传递给JS层或者直接触发跳转逻辑即可
}

方案二:通知弹出逻辑完全交给JS层处理(更推荐,前后台逻辑统一)

删掉原生层onMessageReceived中自行构建通知的代码,仅保留日志打印即可,推送事件会自动抛给Capacitor的推送插件,此时JS层的pushNotificationReceived就可以正常触发,你在这个回调里调用createLocalNotification弹出本地通知即可,本地通知的点击事件会自动触发pushNotificationActionPerformed回调,和后台逻辑完全统一,不需要额外做原生适配。


额外检查项

  • 你通过Postman调用FCM接口时,建议发送数据消息(即payload中仅包含data字段,不包含notification字段),如果包含notification字段,前台时会被系统直接拦截,不会触发onMessageReceived和JS层的接收回调。
  • 检查AndroidManifest.xml中是否已经配置了FCM的服务和相关权限,以及MainActivity的启动模式是否配置正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:39:04