Flutter iOS适配Firebase Messaging 7.0.0升级9.0.1方法咨询
Firebase Messaging 9.0.1 核心API变更说明
- 旧版7.0.0中使用的
onIosSettingsRegistered流、requestNotificationPermissions()方法、IosNotificationSettings类已从公开API中完全移除,调用时会直接抛出未定义的编译错误 - iOS端权限申请逻辑不再绑定独立的全局事件流,改为通过异步方法的返回值直接传递用户授权结果;9.0.1版本基于强制空安全实现,所有可能为null的返回值都需要做显式空值判断,否则会触发编译报错
报错点的替代实现方案
1. 权限申请与原回调逻辑替换
原来的两段iOS初始化代码(监听设置注册事件、申请通知权限)可以合并为一个异步流程,完全不需要保留之前的iosSubscription流订阅:
- 权限申请统一调用
_fcm.requestPermission()方法,直接接收返回的NotificationSettings对象判断用户授权状态 - 原
onIosSettingsRegistered监听器里的逻辑,直接放到授权成功的判断分支里执行即可
// 替换原initState中的iOS初始化逻辑 if (Platform.isIOS) { final NotificationSettings settings = await _fcm.requestPermission( alert: true, badge: true, sound: true, ); // 仅当用户授权通知权限后再执行后续逻辑 if (settings.authorizationStatus == AuthorizationStatus.authorized) { await _saveDeviceToken(); } }
2. 残留逻辑优化
- 原代码中的
StreamSubscription iosSubscription变量可以直接删除,没有对应事件源后保留只会造成不必要的内存泄漏风险 - 原代码中直接调用
FirebaseAuth.instance.currentUser.uid的写法会因为空安全校验报错,需要增加空值判断 - 建议补充注册
onTokenRefresh流监听,当FCM自动轮换设备token时自动同步最新值到Firestore,避免token失效导致推送无法送达
补充监听写法:
_fcm.onTokenRefresh.listen((newToken) { // 复用_saveDeviceToken的存储逻辑,把传入值替换为回调返回的newToken即可 });
修正后的完整可运行代码
final FirebaseMessaging _fcm = FirebaseMessaging.instance; @override void initState() { super.initState(); if (Platform.isIOS) { _setupIosNotificationPermission(); } } Future<void> _setupIosNotificationPermission() async { final NotificationSettings settings = await _fcm.requestPermission( alert: true, badge: true, sound: true, ); if (settings.authorizationStatus == AuthorizationStatus.authorized) { await _saveDeviceToken(); } // 监听token自动刷新 _fcm.onTokenRefresh.listen((newToken) async { final uid = FirebaseAuth.instance.currentUser?.uid; if (uid == null) return; await FirebaseFirestore.instance .collection('users') .doc(uid) .collection('tokens') .add({ 'token': newToken, 'createdAt': FieldValue.serverTimestamp(), 'platform': Platform.operatingSystem }); }); } _saveDeviceToken() async { final uid = FirebaseAuth.instance.currentUser?.uid; if (uid == null) return; final fcmToken = await _fcm.getToken(); if (fcmToken != null) { await FirebaseFirestore.instance .collection('users') .doc(uid) .collection('tokens') .add({ 'token': fcmToken, 'createdAt': FieldValue.serverTimestamp(), 'platform': Platform.operatingSystem }); } }
内容的提问来源于stack exchange,提问作者Amxela
相关产品推荐
相关产品推荐

