Flutter iOS端调用Firebase Cloud Messaging通知权限请求弹窗不弹出怎么办
修复方案
核心问题原因
权限弹窗无法唤起主要来自以下几个常见错误:
- 代码中缺少Firebase初始化步骤,FCM实例未就绪就调用权限请求接口会静默失败
- 异步的
permission函数没有加await等待执行完成,请求逻辑可能被启动流程打断 - 未提前判断当前权限状态,若用户之前已经拒绝过权限,iOS系统不会再次触发弹窗
- Xcode项目侧的推送相关配置缺失
代码修复
调整后的完整启动逻辑如下:
Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); // 新增Firebase初始化 await Firebase.initializeApp(); if (Platform.isIOS) { // 等待权限请求逻辑执行完成 await permission(); } runApp(const MyApp()); } Future<void> permission() async { // 先获取当前已有权限状态,避免重复请求被系统拦截 NotificationSettings existingSettings = await messaging.getNotificationSettings(); if (existingSettings.authorizationStatus == AuthorizationStatus.notDetermined) { // 只有未确定权限状态时才发起请求 NotificationSettings settings = await messaging.requestPermission( alert: true, announcement: false, badge: true, carPlay: false, criticalAlert: false, provisional: false, sound: true, ); if (settings.authorizationStatus == AuthorizationStatus.authorized || settings.authorizationStatus == AuthorizationStatus.provisional) { FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); await FirebaseMessaging.instance .setForegroundNotificationPresentationOptions( alert: true, // iOS前台通知横幅 badge: true, sound: true, ); } else { SystemChannels.platform.invokeMethod('SystemNavigator.pop'); } } else if (existingSettings.authorizationStatus == AuthorizationStatus.denied) { // 权限已被拒绝,可自定义弹窗引导用户去系统设置开启后再执行后续逻辑 SystemChannels.platform.invokeMethod('SystemNavigator.pop'); } else { // 已有权限直接配置FCM FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); await FirebaseMessaging.instance .setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true, ); } }
配套配置检查
你需要确认Xcode侧的配置正确:
- 打开iOS工程下的
Runner.xcworkspace,进入Signing & Capabilities页,添加Push Notifications能力 - 添加
Background Modes能力,勾选其中的Remote notifications选项 - 确认Apple Developer后台对应Bundle ID的推送证书已配置生效
测试注意
如果之前测试时已经拒绝过权限,需要先卸载应用再重新安装测试,才能再次触发系统权限弹窗。
内容的提问来源于stack exchange,提问作者Mattia Mora
相关产品推荐
相关产品推荐

