-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Open
Description
Describe
I am trying to show a heads-up push notification locally based on certain conditions. This works as expected on Android but not on iOS.
On iOS:
If I set alert: true in setForegroundNotificationPresentationOptions, the notification appears twice (one from the system and one from my local logic).
If I set alert: false or omit setForegroundNotificationPresentationOptions, the push notification never appears.
I checked including #2474 and #2196. They contain relevant information but don’t fully resolve this issue. Please let me know if I missed something.
Question
@MaikuB
Is this the intended behavior on iOS, or is it a bug?
If this is expected, is creating a custom push alert the only way to show a heads-up push message?
To Reproduce
- Use Firebase Cloud Messaging (FCM) to receive push notifications.
- Set
setForegroundNotificationPresentationOptions(alert: false, badge: true, sound: true). - Listen to
FirebaseMessaging.onMessageand show a local notification conditionally. - Observe that no notification appears in the foreground.
- Set
alert: trueand observe that notifications appear twice.
Expected behavior
- I expect to be able to show or hide the push notification conditionally when the app is in the foreground.
- On iOS, setting alert: false completely prevents the notification from appearing, while setting
alert: truealways shows it.
Environment
- Flutter version: 3.27.1
- flutter_local_notifications version: 17.2.4, 19.0.0
- firebase_messaging version: 15.1.3, 15.2.4
- Device 1: iPhone 13 Pro, iOS 18.3.2
- Device 2: iPhone 13, iOS 18.0
Sample code
// Before runApp
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await setupFlutterNotifications();
await FirebaseMessaging.instance.setAutoInitEnabled(true);
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
await showFlutterNotification(message);
});
await configPushCondition();// Configuration
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
late AndroidNotificationChannel channel;
bool isFlutterLocalNotificationsInitialized = false;
Future<void> setupFlutterNotifications() async {
if (isFlutterLocalNotificationsInitialized) return;
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: false,
badge: false,
sound: false,
);
channel = const AndroidNotificationChannel(
'max_importance_channel',
'max Importance Notifications',
description: 'This channel is used for important notifications.',
importance: Importance.max,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
const initializationSettings = InitializationSettings(
android: AndroidInitializationSettings('@mipmap/launcher_icon'),
iOS: DarwinInitializationSettings(),
);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) {
_handleLocalNotificationTap(response.payload);
},
);
isFlutterLocalNotificationsInitialized = true;
}
Future<void> showFlutterNotification(RemoteMessage message) async {
final RemoteNotification? notification = message.notification;
final AndroidNotification? android = message.notification?.android;
if (notification != null && android == null) {
await flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
const NotificationDetails(
iOS: DarwinNotificationDetails(
presentAlert: true,
presentBadge: true,
presentBanner: true,
presentSound: true,
presentList: true,
interruptionLevel: InterruptionLevel.timeSensitive,
),
),
);
}
}
Future<void> configPushCondition() async {
final fcm = FirebaseMessaging.instance;
await fcm.requestPermission();
if (Platform.isIOS) {
// return when Simulator
var apnsToken = await fcm.getAPNSToken();
if (apnsToken == null) {
await Future<void>.delayed(const Duration(seconds: 1));
apnsToken = await fcm.getAPNSToken();
if (apnsToken == null) {
print(
'Can not subscribe topic on this launch by getAPNSToken failed',
);
return;
}
}
}
print('fcmToken: ${await fcm.getToken()}');
}
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels