firebase / flutterfire

🔥 A collection of Firebase plugins for Flutter apps.
https://firebase.google.com/docs/flutter/setup
BSD 3-Clause "New" or "Revised" License
8.73k stars 3.98k forks source link

[firebase_messaging]: the callback for onBackgroundMessage do not invoked #13442

Open rednez opened 1 month ago

rednez commented 1 month ago

Is there an existing issue for this?

Are you aware of the differences between iOS and Android background message handling?

Do you have an active Apple Developer account?

Are you 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?

xcode_screen

Have you created an APNs key in your Apple Developer account & uploaded this APNs key to your Firebase console?

firebase_screenshot

Have you disabled method swizzling for Firebase in your app?

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CADisableMinimumFrameDurationOnPhone</key>
    <true/>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleDisplayName</key>
    <string>Zizi</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>zizi</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>$(FLUTTER_BUILD_NAME)</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>$(FLUTTER_BUILD_NUMBER)</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UIApplicationSupportsIndirectInputEvents</key>
    <true/>
    <key>UIBackgroundModes</key>
    <array>
        <string>remote-notification</string>
        <string>fetch</string>
        <string>processing</string>
    </array>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
</dict>
</plist>

Are you sending messages to your app from the Firebase Admin SDK?

// NestJS service
// "firebase-admin": "^12.6.0",
import { messaging } from 'firebase-admin';

 async send(token: string): Promise<void> {
    messaging()
      .send({
        token,
        notification: {
          title: 'Some message',
          body: `Some body`,
        },
        data: {
          type: 'chat',
          customMessage: 'Hello world',
        },
      })
      .catch((error) => {
        console.log('error sending notification', error.message);
      });
  }

sendToDevice marked as deprecated, so I don't use it.

Have you requested permission from the user 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?

There is no any records for *firebase filter

Additional context and comments

Run app in Debug flutter run mode and in release flutter run --release mode. No matter.

main.dart

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

import 'firebase_options.dart';

// This callback do not invoking
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  print("Handling a background message: ${message.messageId}");
}

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  FirebaseMessaging messaging = FirebaseMessaging.instance;

  NotificationSettings settings = await messaging.requestPermission(
    alert: true,
    announcement: false,
    badge: true,
    carPlay: false,
    criticalAlert: false,
    provisional: false,
    sound: true,
  );

  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    print('Got a message whilst in the foreground!');
    print('Message data: ${message.data}');

    if (message.notification != null) {
      print('Message also contained a notification: ${message.notification}');
    }
  });

  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String text = 'Hello world!';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          children: [Text(text)],
        ),
      ),
    );
  }
}

pubspec.yaml

name: zizi
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: ^3.5.3

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.8
  firebase_core: ^3.6.0
  firebase_messaging: ^15.1.3
  shared_preferences: ^2.3.2

dev_dependencies:
  flutter_test:
    sdk: flutter

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^4.0.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter packages.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/to/resolution-aware-images

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/to/asset-from-package

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/to/font-from-package
SelaseKay commented 1 month ago

Hi @rednez , Thanks for submitting this report. I'm able to reproduce this issue. Reproduced with firebase_messaging example app

ovidiuadorian-yonder commented 1 month ago

I have the same issue. I can also reproduce it and it impacts our development as we relied on that callback

AshiqNoor commented 1 month ago

i'm able to reproduce this issue in iOS 17 and iOS 18. in iOS 15 it works me.

Daniel-BD commented 1 month ago

Have you tried downgrading to BoM 2.4.1. I'm not suggesting that's a viable solution, but it seems that BoM 2.5.0 and forward have broken push notifications for some iOS Flutter apps. Could be related to this: https://github.com/firebase/flutterfire/issues/13287

Downgrading to BoM 2.4.1 (firebase_messaging 15.0.4) works for me, any higher version doesn't work.

VinRu5 commented 1 month ago

Have you tried downgrading to BoM 2.4.1. I'm not suggesting that's a viable solution, but it seems that BoM 2.5.0 and forward have broken push notifications for some iOS Flutter apps. Could be related to this: #13287

Downgrading to BoM 2.4.1 (firebase_messaging 15.0.4) works for me, any higher version doesn't work.

I have the same problem. This works in debug for me but not in release.

Daniel-BD commented 1 month ago

Have you tried downgrading to BoM 2.4.1. I'm not suggesting that's a viable solution, but it seems that BoM 2.5.0 and forward have broken push notifications for some iOS Flutter apps. Could be related to this: #13287 Downgrading to BoM 2.4.1 (firebase_messaging 15.0.4) works for me, any higher version doesn't work.

I have the same problem. This works in debug for me but not in release.

I hadn't even tried release mode, but now that I do onBackgroundMessage isn't invoked for me either.

In debug, both onBackgroundMessage and onMessage are invoked when the app is in background/foreground respectivly. But in release mode, only onMessage fires in foreground. Background doesn't work.

And in higher versions than BoM 2.4.1, nothing works in debug or release.

EDIT: onBackgroundMessage DOES work on iOS in BoM 2.4.1. However, iOS restricts the number of background push messages/processing an app can do, so it stops working after a while. Then you have to wait a while (no idea how long, I waited two hours) and it will work again. So when developing you may send lots of push messages and get throttled by iOS. I was able to send 8 messages before they stopped coming in.

Edit 2: to be clear, I'm talking about data messages, not notification messages (read firebase messaging docs for more info about the differences)

So I have no issue with BoM 2.4.1 at all!

yashpalzala commented 1 month ago

Any updates on this issue? @SelaseKay

adityasethipsi commented 1 month ago

I'm facing this on android and IOS as well. Any update on this?

Poloten commented 1 month ago

EDIT: onBackgroundMessage DOES work on iOS in BoM 2.4.1. However, iOS restricts the number of background push messages/processing an app can do, so it stops working after a while. Then you have to wait a while (no idea how long, I waited two hours) and it will work again. So when developing you may send lots of push messages and get throttled by iOS. I was able to send 8 messages before they stopped coming in.

So I have no issue with BoM 2.4.1 at all!

It's not normal behaviour, try to use some chat applications like telegram you get a lot of push without restrictions. That's bug only reproduce on flutter firebase.

Daniel-BD commented 1 month ago

EDIT: onBackgroundMessage DOES work on iOS in BoM 2.4.1. However, iOS restricts the number of background push messages/processing an app can do, so it stops working after a while. Then you have to wait a while (no idea how long, I waited two hours) and it will work again. So when developing you may send lots of push messages and get throttled by iOS. I was able to send 8 messages before they stopped coming in. So I have no issue with BoM 2.4.1 at all!

It's not normal behaviour, try to use some chat applications like telegram you get a lot of push without restrictions. That's bug only reproduce on flutter firebase.

No, it's perfectly normal actually. We use data messages (not notification messages) and those are restricted. Read more here: https://firebase.google.com/docs/cloud-messaging/concept-options and https://firebase.google.com/docs/cloud-messaging/flutter/receive

data messages and notification messages are very different and should not be confused. Notification messages never invokes onBackgroundMessage. So chat apps are using notification messages for unlimited push messages like you're talking about.

Poloten commented 1 month ago

notification

No, it's perfectly normal actually. We use data messages (not notification messages) and those are restricted. Read more here: https://firebase.google.com/docs/cloud-messaging/concept-options and https://firebase.google.com/docs/cloud-messaging/flutter/receive

data messages and notification messages are very different and should not be confused. Notification messages never invokes onBackgroundMessage. So chat apps are using notification messages for unlimited push messages like you're talking about.

I use notification message, not silent push and get the same behaviour. When message received onBackgroundMessage works (probably 8-10) count after that 'onBackgroundMessage' don't invoked.

seoleo96 commented 1 month ago

I'm facing this on IOS. Any update on this?

vpakhomov commented 1 month ago

Same problem on ios 17,18 please help. Application doesn't work correctly on ios.

sweettirexkiller commented 1 month ago

Same problem on iOS18, please help.

anhkhoa1208py commented 1 month ago

Same problem on ios 17,18 please help. Application only work on ios 15

Denis0744 commented 1 month ago

Only works on iOS 16 and below. Flutterfire currently only android ? Ios not maintained since 2023 ?

russellwheatley commented 1 month ago

Hey @rednez, I have a fix for background message handling in iOS that should allow you to turn FirebaseAppDelegateProxyEnabled back to true.

Could you try this branch: https://github.com/firebase/flutterfire/pull/13525, and let me know if it works for you?

rednez commented 1 month ago

Hey @rednez, I have a fix for background message handling in iOS that should allow you to turn FirebaseAppDelegateProxyEnabled back to true.

Could you try this branch: #13525, and let me know if it works for you?

Hello @russellwheatley. I installed your 'messaging-13476' branch today. Unfortunately, the onBackgroundMessage doesn't invokes. Should I do some additional setup?

pranay-vertofx commented 1 month ago

In my case I just added this below code

 override func application(
       _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
       fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
     ) {
       super.application(
         application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler
       )
     }

in AppDelegate.swift file and it started working

Poloten commented 1 month ago

Hey @rednez, I have a fix for background message handling in iOS that should allow you to turn FirebaseAppDelegateProxyEnabled back to true. Could you try this branch: #13525, and let me know if it works for you?

Hello @russellwheatley. I installed your 'messaging-13476' branch today. Unfortunately, the onBackgroundMessage doesn't invokes. Should I do some additional setup?

<key>FirebaseAppDelegateProxyEnabled</key>
<true/>

(info.plist file)

cd ios > pod install / pod update

russellwheatley commented 1 month ago

Hey @rednez, I have a fix for background message handling in iOS that should allow you to turn FirebaseAppDelegateProxyEnabled back to true. Could you try this branch: #13525, and let me know if it works for you?

Hello @russellwheatley. I installed your 'messaging-13476' branch today. Unfortunately, the onBackgroundMessage doesn't invokes. Should I do some additional setup?

You must have a different issue as it now works for me and is confirmed by a couple of other users that this fixes background message handling.

russellwheatley commented 1 month ago

In my case I just added this below code

 override func application(
       _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
       fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
     ) {
       super.application(
         application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler
       )
     }

in AppDelegate.swift file and it started working

No need to update your AppDelegate with the fix on the branch I posted.

niosme commented 3 weeks ago

In my case I just added this below code

 override func application(
       _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
       fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
     ) {
       super.application(
         application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler
       )
     }

in AppDelegate.swift file and it started working

No need to update your AppDelegate with the fix on the branch I posted.

With the branch It works perfectly :)

kamjony commented 3 weeks ago

@russellwheatley When will the fix be available to pub.dev?? I am using it like this in my pubspec.yaml

 firebase_messaging:
    git:
      url: https://github.com/firebase/flutterfire.git
      path: packages/firebase_messaging/firebase_messaging
      ref: main

Also added the following to my info.plist

<key>FirebaseAppDelegateProxyEnabled</key>
<true/>

Then cd/ios, pod install and pod update but still no changes

// This callback is still not invoked

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  print("Handling a background message: ${message.messageId}");
}

My console does not print the print statement still. I receive notification if I use the notification parameter when app is minimized but still the callback is never invoked. I send notification the following way:

{
   "message":{
      "token":"client_token",
      "data":{
        "hello": "This is a Firebase Cloud Messaging device group message!"
      },
    //   "notification": {
    //     "title":"Title",
    //     "body": "body"
    //   },
      "apns": {
      "headers": {
        "apns-priority": "10"
      },
      "payload": {
        "aps": {
          "badge": 1
        },
        "mutable_content": true,
        "content_available" : true

      }
    }
   }
}

Please let me know what I am doing wrong. Stuck here for days."

@niosme Please could you check if the above is ok? As I do not see any changes. Any help is greatly appreciated, Thanks

niosme commented 3 weeks ago

@russellwheatley When will the fix be available to pub.dev?? I am using it like this in my pubspec.yaml

firebase_messaging:
   git:
     url: https://github.com/firebase/flutterfire.git
     path: packages/firebase_messaging/firebase_messaging
     ref: main

In the next week they should release the next version as @russellwheatley said :)

Also added the following to my info.plist

<key>FirebaseAppDelegateProxyEnabled</key>
<true/>

This inside info.plist is NOT needed. Do a flutter clean flutter pub get

Close and reopen flutter also.

Then cd/ios, pod install and pod update but still no changes

// This callback is still not invoked

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  print("Handling a background message: ${message.messageId}");
}

you should use this also to trigger the function you got inside your initialize function to be fired once.

 // Handle background messages
    FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
{
   "message":{
      "token":"client_token",
      "data":{
        "hello": "This is a Firebase Cloud Messaging device group message!"
      },
    //   "notification": {
    //     "title":"Title",
    //     "body": "body"
    //   },
      "apns": {
      "headers": {
        "apns-priority": "10"
      },
      "payload": {
        "aps": {
          "badge": 1
        },
        "mutable_content": true,
        "content_available" : true

      }
    }
   }
}

i use this payload for silent notifications

remove the priority and add those 4 things inside the aps

                    $apnsConfig = ApnsConfig::fromArray([
                        'payload' => [
                            'aps' => [
                                'mutable-content' => 1,
                                'content-available' => 1, // Required for silent notifications
                                'alert' => "", //add this for silent notifications
                                'sound' => 'default', //add this for silent notifications
                            ],
                        ],
                    ]);

Check this for what ios expects :

https://developer.apple.com/documentation/usernotifications/generating-a-remote-notification

and this for firebase in php:

https://firebase-php.readthedocs.io/en/7.15.0/cloud-messaging.html#adding-target-platform-specific-configuration

Hope that helps. Ensure you have used flutter clean and flutter pub get. restart the app or whatever because it maybe cached some things.

pvc97 commented 3 weeks ago

I've switched to the latest commit, but onBackgroundMessage only works in debug mode on some devices.

I don't know why. Can somebody help me?

dhara6894 commented 3 weeks ago

I've switched to the latest commit, but callback for onBackgroundMessage do not invoked.

kangmyonggyu commented 2 weeks ago

I've switched to the latest commit, but background notification not working...

iPhone 14 - iOS 18.0.1 – only debug working, release not working

FarhanAbid01 commented 2 weeks ago

I also tried all above mentioned solution still none of them works for me onBackgroundMessage is not getting invoked tried on Iphone 15 Pro Max - IOS 18.0.1 -- only debug works but release not working

rednez commented 2 weeks ago

I tried again on last release firebase_messaging 15.1.4:

pvc97 commented 2 weeks ago

I tried again on last release firebase_messaging 15.1.4:

  • Works only in Debug mode and only if data is sending.
  • If send a notification (with or without a data) then it's not working.
  • iOS 18.1, iPhone 15 Pro.

@kangmyonggyu explained why onBackgroundMessage is not working in release mode. Do you think this explanation is correct?

https://github.com/firebase/flutterfire/issues/13643#issuecomment-2465564267