Flutter接入FCM搭配Node.js后端时前后台消息回调触发异常问题
核心问题根因
后端发送的FCM消息为纯数据类型,未携带notification字段,不符合FCM不同回调的触发条件,两个场景的异常表现均由此导致。
场景1问题说明与解决
FirebaseMessaging.onMessageOpenedApp的触发前提是用户点击系统通知栏的推送消息唤起应用,纯数据类型的FCM消息不会被FCM SDK自动弹出到通知栏,没有可点击的通知入口,自然不会触发该回调。而后台状态下收到纯数据消息默认触发backgroundHandler属于FCM的正常行为。
如需触发onMessageOpenedApp,可选择两种方案:
- 后端推送时添加
notification字段,由FCM SDK自动弹出系统通知 - 保留纯数据消息,在
backgroundHandler中调用flutter_local_notifications主动弹出本地通知,自行监听本地通知的点击事件处理业务逻辑
场景2问题说明与解决
FirebaseMessaging.onMessage本身仅在应用处于前台活跃状态时触发,应用终止状态下不会触发该回调,属于正常逻辑。getInitialMessage返回null的原因是:仅当用户点击带notification字段的推送消息唤起被终止的应用时,该方法才会返回对应的消息体,纯数据消息不会被存入该回调的返回值中。
另外当前代码中直接对message执行强解包!,未做非空判断,会在消息为空时直接抛出空异常,需要先判空再处理。
具体修改步骤
1. 调整Node.js后端推送代码
给推送消息添加notification字段,自定义业务参数保留在data中:
var message={ notification: { title:'Go Notification', body:'Checking the app from node', }, data:{ // 存放自定义业务参数 }, token:registrationToken };
2. 修复前端空安全问题
修改getInitialMessage的处理逻辑,避免空异常:
FirebaseMessaging.instance.getInitialMessage().then((message) { print("Get Initial method called"); // 先判空再处理业务 if (message != null) { Fluttertoast.showToast( msg: message.data.toString(), toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIosWeb: 3, backgroundColor: Colors.red, textColor: Colors.white, fontSize: 16.0); } });
额外注意事项
- 安卓平台下,国内厂商对后台推送的限制较多,需要给应用开启自启动、后台活动权限,否则应用被划掉后可能无法收到推送
- 当前使用的
firebase_messaging: ^10.0.1版本较旧,存在部分已知的回调异常bug,如修改后仍有问题可升级到最新稳定版排查
内容的提问来源于stack exchange,提问作者Sharath Appesh
相关产品推荐
相关产品推荐

