flutterfire
flutterfire copied to clipboard
[firebase_messaging]: Receiving notifications in iOS background/terminated not working
Is there an existing issue for this?
- [X] I have searched the existing issues.
Are you aware of the differences between iOS and Android background message handling?
- [X] I understand that iOS and Android background messages behave differently, and I've designed my application with that in mind.
Do you have an active Apple Developer account?
- [X] I have an active Apple Developer account.
Are you using a physical iOS device to test background messages?
- [X] I am using a physical iOS device to test background messages.
Have you enabled "Remote Notifications" & "Background Mode" (Checking options for "Background Processing" & "Remote Notifications") in your app's Xcode project?
yes
Have you created an APNs key in your Apple Developer account & uploaded this APNs key to your Firebase console?
yes
Have you disabled method swizzling for Firebase in your app?
Yes and tried with YES or No, it not works
Are you sending messages to your app from the Firebase Admin SDK?
Yes, lock at my comments
Have you requested permission from the user to receive notifications?
- [X] I have the relevant permission to receive notifications.
Have you used the 'Console' application on your macOS device to check if the iOS device's system is throttling your background messages?
No I didn't use it
Additional context and comments
Iam sending notifications using Firebase Admin SDK for PHP and receiving in Flutter app using firebase and flutter_local_notification package.
My flutter app receiving notifications well in Android devices in foreground, background and terminated. iOS devices receiving notifications only in foreground. Notifications presents by flutter_local_notification package.
The problem that app not receiving notifications in ios device when the app in background and terminated.
Problem: To get notifications in ios device when the app in background and terminated I need to set 'alert' => $data, then the app receiving notifications, BUT notifications sends directly to the device not to the app via flutter_local_notification.
I want to present notifications in all modes and devices via flutter_local_notification.
Is there any thing which disable notifications receiving in ios device when the app in background and terminate? How to solve it?
Flutter: 3.22.2
firebase_core: ^3.1.0 firebase_messaging: ^15.0.1 firebase_database: ^11.0.1 flutter_local_notifications: ^17.1.2
PHP
$data = [
'title' => $title,
'body' => $description,
'id' => $id,
];
$message = CloudMessage::withTarget('token', $user['firebase_token'])
// ->withNotification(Notification::create($title, $description))
->withData($data);
if(strtolower($user['platform']) == 'android'){
$config = AndroidConfig::fromArray([
'ttl' => '3600s',
'priority' => 'normal',
'data' => [
'title' => $title,
'body' => $description,
'icon' => 'stock_ticker_update',
'color' => '#f45342',
'sound' => 'default',
],
]);
$message = $message->withAndroidConfig($config);
}
else if(strtolower($user['platform']) == 'ios'){
$config = ApnsConfig::fromArray([
'headers' => [
'apns-priority' => '5',
],
'payload' => [
'aps' => [
'contentAvailable'=> true,
// 'alert' => $data,
'badge' => 1,
'sound' => 'default',
"mutable-content" => 1,
],
'data' => $data,
],
]);
$message = $message->withApnsConfig($config);
}
try {
$messaging->send($message);
} catch (Exception $e) {
echo "Error sending message: " . $e->getMessage();
}
AppDelegate.swift
import UIKit
import Flutter
import flutter_local_notifications
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
GeneratedPluginRegistrant.register(with: registry)
}
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Hi blue492 please show how u subscibe on message. Dont forget u need call await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); before subsrcibe
bool isInitialApp = false;
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
if (!isInitialApp) await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// logic
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
if (!isInitialApp) await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
isInitialApp = true;
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
}
Hi blue492 please show how u subscibe on message. Dont forget u need call await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); before subsrcibe
bool isInitialApp = false; @pragma('vm:entry-point') Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { if (!isInitialApp) await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); // logic } Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); if (!isInitialApp) await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); isInitialApp = true; FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler); }
Hi @Poloten I did already as your code, it's not works.
I added print in firebaseMessagingBackgroundHandler, no calls happen via onBackgroundMessage when I send the notification and app running in background.
It seems that ios disable notifications when the app in background/terminated
blue492 u use firebase token ? I mean u need that:
Future<String?> getToken() async {
if (Platform.isIOS) {
var apns = await firebaseInstance.getAPNSToken();
debugPrint('apns $apns ');
}
var firebase = await firebaseInstance.getToken();
debugPrint('token $firebase');
return firebase;
}
and check FirebaseMessaging.onMessage.listen(showPushAppRunning); this fire if app is open.
blue492 u use firebase token ? I mean u need that:
Future<String?> getToken() async { if (Platform.isIOS) { var apns = await firebaseInstance.getAPNSToken(); debugPrint('apns $apns '); } var firebase = await firebaseInstance.getToken(); debugPrint('token $firebase'); return firebase; }and check FirebaseMessaging.onMessage.listen(showPushAppRunning); this fire if app is open.
Do you mean that I should use apns token (getAPNSToken) when it is ios device? and getToken() in android? I tested apns now for ios but it not works in FirebaseMessaging.onMessage.listen, no calls happen
I didn't understand what you mean with apns variable in your example if you don't use it anywhere in the function.
blue492 u use firebase token ? I mean u need that:
Future<String?> getToken() async { if (Platform.isIOS) { var apns = await firebaseInstance.getAPNSToken(); debugPrint('apns $apns '); } var firebase = await firebaseInstance.getToken(); debugPrint('token $firebase'); return firebase; }and check FirebaseMessaging.onMessage.listen(showPushAppRunning); this fire if app is open.
Do you mean that I should use apns token (getAPNSToken) when it is ios device? and getToken() in android? I tested apns now for ios but it not works in FirebaseMessaging.onMessage.listen, no calls happen
I didn't understand what you mean with apns variable in your example if you don't use it anywhere in the function.
No, in Apple device you shoud first call await firebaseInstance.getAPNSToken(); and then call await firebaseInstance.getToken() and use firebaseToken. If you don't call the method getAPNSToken() - nothing will work.
blue492 u use firebase token ? I mean u need that:
Future<String?> getToken() async { if (Platform.isIOS) { var apns = await firebaseInstance.getAPNSToken(); debugPrint('apns $apns '); } var firebase = await firebaseInstance.getToken(); debugPrint('token $firebase'); return firebase; }and check FirebaseMessaging.onMessage.listen(showPushAppRunning); this fire if app is open.
Do you mean that I should use apns token (getAPNSToken) when it is ios device? and getToken() in android? I tested apns now for ios but it not works in FirebaseMessaging.onMessage.listen, no calls happen I didn't understand what you mean with apns variable in your example if you don't use it anywhere in the function.
No, in Apple device you shoud first call await firebaseInstance.getAPNSToken(); and then call await firebaseInstance.getToken() and use firebaseToken. If you don't call the method getAPNSToken() - nothing will work.
I tested, iam getting token for apns and firebase, but i still getting notifications only when app is open call to FirebaseMessaging.onMessage.listen,
No calls/triggers to FirebaseMessaging.onBackgroundMessage when app in the background firebaseMessagingBackgroundHandler
try to send with Notification object (title, body) https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#resource:-message
try to send with Notification object (title, body) https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#resource:-message
'alert' object works, not notification ref: https://firebase-php.readthedocs.io/en/stable/cloud-messaging.html
The problem still notifications send directly to device not trigger on
FirebaseMessaging.onBackgroundMessage
firebaseMessagingBackgroundHandler
in firebaseMessagingBackgroundHandler I use flutter_local_notifications to present the message
firebaseMessagingBackgroundHandler trigger only in Android
can u show screenshot from xcode "Background modes"
To check the status of your push notification, please follow the steps below.
- Open the Console app on your Mac
- Select your iPhone from the devices list on the left hand side
- Filter messages by typing in your Bundle ID (e.g. The Firebase Messaging example app bundle ID is 'io.flutter.plugins.firebase.messaging') into the search box and pressing enter. in search field you can write your bundle id 'com.adasd.app' and 'flutter'.
- Press the clear button to clean the history.
- Now send the message to your device
That's logs may help you
@Poloten yes I can see in Console app that the notification is coming with the data I sent, but why FirebaseMessaging.onBackgroundMessage don't trigger ?
@Poloten yes I can see in Console app that the notification is coming with the data I sent, but why
FirebaseMessaging.onBackgroundMessagedon't trigger ?
did you get permission ?
await firebaseInstance.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: true,
provisional: false,
sound: true,
);
@Poloten yes I can see in Console app that the notification is coming with the data I sent, but why
FirebaseMessaging.onBackgroundMessagedon't trigger ?did you get permission ?
await firebaseInstance.requestPermission( alert: true, announcement: false, badge: true, carPlay: false, criticalAlert: true, provisional: false, sound: true, );
yes I get permission
Here are some logs from Console app, hope it can help
Received incoming message on topic .com.domain.name at priority 10
[.com.domain.name] Received remote notification request xxxx-xxxx [ waking: 1, hasAlertContent: 0, hasSound: 1 hasBadge: 1 hasContentAvailable: 1 hasMutableContent: 1 pushType: Alert]
[.com.domain.name] Process delivery of push notification xxxx-xxxx
[.com.domain.name] Content-available push notifications are only supported on-device for iOS, watchOS, and tvOS
[.com.domain.name] Suppressing sound on user visible notification xxxx-xxxx because it has no alert and the app is in the background
[.com.domain.name] Badge can be set for notification xxxx-xxxx: 1 [ canBadge: 1 badgeNumber: 1 ]
[.com.domain.name] Saving notification 3D40-185A: NO [ hasAlertContent: NO, shouldPresentAlert: YES settingsShouldSave: YES]
I dont't use flutterlocalnotification. But in documentation it require:
You need to configure a top level or static method which will handle the action:
@pragma('vm:entry-point')
void notificationTapBackground(NotificationResponse notificationResponse) {
// handle action
}
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse notificationResponse) async {
// ...
},
onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
);
If nothing happend try to add FirebaseApp.configure(). And check what maybe your application have another error
import UIKit
import Flutter
import FirebaseCore
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
I have already implemented code above, I got error with FirebaseApp.configure() so I removed it.
It still same issue FirebaseMessaging.onBackgroundMessage don't trigger in ios.
@blue492 - to send silent messages (i.e data only), make sure you do not send a notification payload (i.e remove this).
Ensure you have this set which will allow data only messages to the background handler which will allow you to send notifications via local notifications.
I'd encourage you to use the nodejs script to send messages or at least follow how to send notifications from it.
I have the same issue, iOS background handler won't trigger. Already tried @russellwheatley payload suggestions on the nodejs example script.
I also began to catch this behavior, but it is not constant. In ios 17.5.1 (ios 16 work fine)
Hey @blue492. We need more information to resolve this issue but there hasn't been an update in 7 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.
If you have more information that will help us get to the bottom of this, just add a comment!
@blue492 - to send silent messages (i.e data only), make sure you do not send a notification payload (i.e remove this).
Ensure you have this set which will allow data only messages to the background handler which will allow you to send notifications via local notifications.
I'd encourage you to use the nodejs script to send messages or at least follow how to send notifications from it.
I already tried things you mentioned, but it not works, something prevents notifications to trigger FirebaseMessaging.onBackgroundMessage
"When calling the API, it might be good to set contentAvailable: true."
I am also facing the same issue that FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler) does not trigger when the app is terminated or in the background.
iPhone Device OS - 17.5.1 (iPhone 11) firebase_messaging: ^15.0.3 flutter_local_notifications: ^17.2.1+2
@russellwheatley We really need your attention on this issue. This is really burning issue on our production app.
flutter doctor -v
"When calling the API, it might be good to set contentAvailable: true."
I have already that, but onBackgroundMessage still not trigger
@russellwheatley Any update on this issue? I am eagerly waiting for your response. Your help is required on this.
Facing the same issue. If app is in background (running) it works fine, however, when I closed the app (terminated) and send the notification after X minutes, it won't be able to receive the silent push notifications. @russellwheatley could you please help? Thanks.
Facing the same issue. Background(terminated) notifications working when application installed from Testflight or Android Studio(release mode) but when applicaiton installed from appstore notification working only when app open or in background(running).Im running app with iPhone 12 pro max iOS 17.5.1
I'm having a similar issue in which background messages are not being delivered- Everything works fine when I revert to a previous Firebase BOM, such as this one
Is it the same in your case?
I'm having a similar issue in which background messages are not being delivered- Everything works fine when I revert to a previous Firebase BOM, such as this one
Is it the same in your case?
what was your approach can you tell us step by step