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

如何将FCM通知的data payload传递给导航图起始目的地Fragment参数

FCM同时携带notification与data字段时参数传递方案

问题根源

当FCM消息同时包含notification和data字段、应用处于后台时,系统会直接生成通知栏消息,用户点击后触发的启动Intent由系统构造,所有data payload参数会直接挂载到目标Activity的intent.extras中。导航组件默认不会自动将Activity Intent的参数同步给导航图的起始目的地,因此无法直接通过Fragment参数获取对应值。

可直接传递参数给起始Fragment的解决方案

不需要强制在Fragment中读取Activity的Intent,通过导航组件原生API即可实现和纯data字段FCM消息完全一致的参数传递逻辑:

  1. 恢复导航图起始目的地的startingId参数定义,保留默认值0即可
  2. 在宿主Activity的onCreate方法中,设置导航图时传入Activity Intent的extras:
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    
    val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    // 第二个参数即为传递给起始目的地的参数Bundle
    navController.setGraph(navController.graph, intent.extras)
}
  1. 之后在起始Fragment中即可直接通过by navArgs()正常获取参数:
private val args by navArgs<StartFragmentArgs>()
private val startingId by lazy { args.startingId }

特殊场景适配

如果你的Activity配置了singleTop/singleTask等启动模式,点击通知时会复用已存在的Activity实例,触发onNewIntent回调,需要补充参数同步逻辑:

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    intent ?: return
    val navController = findNavController(R.id.nav_host_fragment)
    // 方式1:重新设置导航图传入新参数(适合需要重置导航栈的场景)
    navController.setGraph(navController.graph, intent.extras)
    
    // 方式2:仅更新当前栈顶目的地的参数,不重置导航栈(适合保留用户操作路径的场景)
    // navController.currentBackStackEntry?.arguments?.putAll(intent.extras)
}

注意事项

  • 需保证导航图中startingId参数的类型和FCM传过来的类型匹配,如果怕类型自动解析出错,可以先手动从Intent中取出startingId转成对应类型后,构造新的Bundle传给setGraph方法
  • 应用在前台时收到带notification的FCM消息,还是会触发FirebaseMessagingService的onMessageReceived回调,按照原有逻辑构造PendingIntent传入参数即可,两端参数获取逻辑完全统一

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 02:39:03