flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

[firebase_messaging]: Receiving notifications in iOS background/terminated not working

Open blue492 opened this issue 1 year ago • 42 comments

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)
   }
}

blue492 avatar Jun 19 '24 12:06 blue492

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);
}

Poloten avatar Jun 19 '24 14:06 Poloten

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 avatar Jun 19 '24 14:06 blue492

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.

Poloten avatar Jun 19 '24 15:06 Poloten

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 avatar Jun 20 '24 06:06 blue492

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.

Poloten avatar Jun 20 '24 07:06 Poloten

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

blue492 avatar Jun 20 '24 07:06 blue492

try to send with Notification object (title, body) https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#resource:-message

Poloten avatar Jun 20 '24 07:06 Poloten

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

blue492 avatar Jun 20 '24 08:06 blue492

can u show screenshot from xcode "Background modes"

Poloten avatar Jun 20 '24 08:06 Poloten

image

blue492 avatar Jun 20 '24 08:06 blue492

To check the status of your push notification, please follow the steps below.

  1. Open the Console app on your Mac
  2. Select your iPhone from the devices list on the left hand side
  3. 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'.
  4. Press the clear button to clean the history.
  5. Now send the message to your device

That's logs may help you

Poloten avatar Jun 20 '24 14:06 Poloten

@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 ?

blue492 avatar Jun 24 '24 06:06 blue492

@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 ?

did you get permission ?

    await firebaseInstance.requestPermission(
      alert: true,
      announcement: false,
      badge: true,
      carPlay: false,
      criticalAlert: true,
      provisional: false,
      sound: true,
    );

Poloten avatar Jun 24 '24 09:06 Poloten

@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 ?

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

blue492 avatar Jun 24 '24 12:06 blue492

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]

blue492 avatar Jun 25 '24 13:06 blue492

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()

Poloten avatar Jun 25 '24 14:06 Poloten

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 avatar Jun 27 '24 11:06 blue492

@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.

russellwheatley avatar Jul 04 '24 08:07 russellwheatley

I have the same issue, iOS background handler won't trigger. Already tried @russellwheatley payload suggestions on the nodejs example script.

11-prog avatar Jul 08 '24 18:07 11-prog

I also began to catch this behavior, but it is not constant. In ios 17.5.1 (ios 16 work fine)

Poloten avatar Jul 09 '24 11:07 Poloten

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!

google-oss-bot avatar Jul 18 '24 01:07 google-oss-bot

@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

blue492 avatar Jul 18 '24 06:07 blue492

"When calling the API, it might be good to set contentAvailable: true."

t-kob avatar Jul 25 '24 08:07 t-kob

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 Screenshot 2024-07-26 at 1 19 06 PM

PITPL-Maulik-Sinroja avatar Jul 25 '24 14:07 PITPL-Maulik-Sinroja

"When calling the API, it might be good to set contentAvailable: true."

I have already that, but onBackgroundMessage still not trigger

blue492 avatar Jul 25 '24 14:07 blue492

@russellwheatley Any update on this issue? I am eagerly waiting for your response. Your help is required on this.

PITPL-Maulik-Sinroja avatar Aug 05 '24 13:08 PITPL-Maulik-Sinroja

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.

csarigumba avatar Aug 14 '24 15:08 csarigumba

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

aliumac avatar Aug 15 '24 09:08 aliumac

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?

pamafe1976 avatar Sep 07 '24 17:09 pamafe1976

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

soumyajitdas365 avatar Sep 11 '24 10:09 soumyajitdas365