flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

[firebase_messaging]: Cloud Messaging: flutter firebase background notification not working for iOS (Callbacks not triggering)

Open petrnymsa opened this issue 8 months ago • 92 comments

Is there an existing issue for this?

  • [x] I have searched the existing issues.

Which plugins are affected?

No response

Which platforms are affected?

No response

Description

Reopening issue #16878 which was closed by stale bot.

This issue persists.

Reproducing the issue

See #16878

Firebase Core version

3.10.1

Flutter Version

3.27.0

Relevant Log Output


Flutter dependencies

Expand Flutter dependencies snippet

Replace this line with the contents of your `flutter pub deps -- --style=compact`.

Additional context and comments

No response

petrnymsa avatar Mar 17 '25 14:03 petrnymsa

I am also facing same issue on last firebase_messaging example. With Flutter 3.29.2 https://github.com/firebase/flutterfire/tree/750e9c20dab1671029cb740c5fa505ac813c6edd/packages/firebase_messaging/firebase_messaging

kirya355 avatar Mar 17 '25 14:03 kirya355

This is a big deal 🚨 We are now unable to receive notifications on iOS since our notification system is based on data-only push notifications. Nothing goes through.

ndelanou avatar Mar 17 '25 17:03 ndelanou

This is a big deal 🚨 We are now unable to receive notifications on iOS since our notification system is based on data-only push notifications. Nothing goes through.

Did you manage to show notifications when the app terminated on iOS before? How to do that? because FCM documentation says it's not possible to show notifications when the app is terminated in iOS. @ndelanou


For this issue, I still receive the background notification (not terminated), but then since evening I haven't received it anymore... it seems the bug is fresh.

dragongesa avatar Mar 18 '25 10:03 dragongesa

Hi @petrnymsa, thanks for the report! I couldn't reproduce the issue on my end. Could you provide detailed steps to help replicate it?

SelaseKay avatar Mar 18 '25 11:03 SelaseKay

They are still same as in original issue. Issue was closed just because of "stale bot" which does not make sense to push community keep "issue" updated.

Issue persists and I am not only one.

Firebase packages are updated. Real device or iOS simulator - behavior is same. background handler or event onMessageOpenedApp are not fired at all. (By the way started to see same behaviour for Android devices too)

petrnymsa avatar Mar 18 '25 11:03 petrnymsa

I couldn't reproduce this behaviour with the firebase_messaging example app. Could you run the example app with your firebase credentials to see if it's still reproducible?

SelaseKay avatar Mar 18 '25 11:03 SelaseKay

How can I try to send notification to example app? How can ours firebase credentials can help?

petrnymsa avatar Mar 18 '25 11:03 petrnymsa

You can test this with the example app by replacing firebase_options.dart with your own. I’d like to confirm whether it's an implementation issue on your end, as I couldn't reproduce it using the example app.

SelaseKay avatar Mar 18 '25 11:03 SelaseKay

Hi @petrnymsa, thanks for the report! I couldn't reproduce the issue on my end. Could you provide detailed steps to help replicate it?

Let me guide you through the steps to reproduce the bug. I'm using the latest firebase_messaging example, and I've made some modifications to test the behavior. The issue occurs when receiving a notification while the app is in the background or terminated. Specifically, the last_received_message_time stored in SharedPreferences appears to be empty when the app is opened.

Here’s the modified Example code and steps to reproduce the issue:

  1. Background Handler I added new lines to the _firebaseMessagingBackgroundHandler to store the timestamp of the received message in SharedPreferences:
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  // New lines to store the timestamp.
  SharedPreferences prefs = await SharedPreferences.getInstance();
  await prefs.setString('last_received_message_time', DateTime.now().toIso8601String());
  // End of new lines.

  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  await setupFlutterNotifications();
  showFlutterNotification(message);
  print('Handling a background message ${message.messageId}');
}
  1. initState Method In the initState method, I added a function _updateLastReceivedMessageTime to retrieve the stored timestamp from SharedPreferences and update the state:
String? _lastReceivedMessageTime;

Future<void> _updateLastReceivedMessageTime() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  setState(() {
    _lastReceivedMessageTime = prefs.getString('last_received_message_time');
  });
}

@override
void initState() {
  super.initState();
  unawaited(_updateLastReceivedMessageTime());
  // ... existing code
}
  1. build Method In the build method, I added a Text widget to display the timestamp and an ElevatedButton to manually refresh the data:
body: SingleChildScrollView(
  child: Column(
    children: [
      MetaCard(
        'Last Received Message Time',
        Column(
          children: [
            Text(_lastReceivedMessageTime ?? 'None'),
          ],
        ),
      ),
      ElevatedButton(
        onPressed: _updateLastReceivedMessageTime,
        child: const Text('Update last received message time'),
      ),
      // ... existing code
    ],
  ),
),

Steps to Reproduce the Issue:

  1. Send a push notification to the device while the app is in the background or terminated.
  2. Open the app after receiving the notification.
  3. Check the Last Received Message Time field. It should display None or an empty value, even though the timestamp was saved in the background handler.

Expected Behavior:

The last_received_message_time should be displayed correctly when the app is opened after receiving a notification in the background or terminated state.

kirya355 avatar Mar 18 '25 14:03 kirya355

Hi @kirya355, I'm still unable to reproduce this issue with your sample. Are you sending the notification via node Admin SDK?

SelaseKay avatar Mar 19 '25 14:03 SelaseKay

Hey there @kirya355 thank you for the reproduction steps. Notifications seem to work fine in the background for me and I have also been unable to reproduce.

MichaelVerdon avatar Mar 19 '25 16:03 MichaelVerdon

I have the same error, works fine in android, but not ios

flutter 3.22.3
firebase_core: ^2.27.0
firebase_messaging: ^14.7.19

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  // in android you can jump here but ios can't

  await Firebase.initializeApp();

  Utils().handleAppBadgeOnMain();
}

main()async{
  await Firebase.initializeApp();

  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}

vienhp1996 avatar Mar 20 '25 07:03 vienhp1996

I have a same issue, it's working fine on android but not working on iOS onBackgroundMessage is never called in ios

kishormainali avatar Mar 20 '25 11:03 kishormainali

Hi @SelaseKay , thank you for trying to reproduce the issue. I'm sending the notification using curl, and the push notification is delivered successfully. However, the _firebaseMessagingBackgroundHandler method is not being called, which is why the timestamp is not saved in SharedPreferences via await prefs.setString('last_received_message_time').

Could you clarify what exactly you were unable to reproduce? Does the _firebaseMessagingBackgroundHandler method work correctly in your environment, and is the timestamp saved as expected? If so, could you share your setup or any additional steps you took to make it work?

Here’s the curl command I’m using to send the notification:

curl --location 'https://fcm.googleapis.com/v1/projects/project_name/messages:send' \
--header 'Authorization: Bearer my_auth_token' \
--header 'Content-Type: application/json' \
--data '{
 "message": {
   "token": "my_fcm_token",
   "notification": {
     "title": "Test",
     "body": "Test Body"
   },
   "android": {
     "priority": "high"
   },
   "apns": {
     "headers": {
       "apns-priority": "10"
     },
     "payload": {
       "aps": {
         "content-available": 1
       }
     }
   }
 }
}'

kirya355 avatar Mar 20 '25 11:03 kirya355

Hi @kirya355, in my case, the background handler worked as expected. I modified the example app with your sample and was able to retrieve the last_received_message_time on the UI.

SelaseKay avatar Mar 20 '25 13:03 SelaseKay

@kirya355 The request you provided works for me as long as you keep a "notification" field in the payload. If you remove it and only pass a "data" payload, the background handler is not called

ndelanou avatar Mar 20 '25 16:03 ndelanou

Hi @SelaseKay , thanks for confirming that the background handler works in your case. Could you please share more details about your testing environment? Specifically:

Platform: Are you testing on Android, iOS, or both? In my case, the issue occurs only on iOS. On Android, everything works as expected, and the _firebaseMessagingBackgroundHandler is called correctly.

Device/Simulator: Are you using a physical device or a simulator for testing? If it's a physical device, could you specify the iOS version?

It would be helpful to understand if there are any differences in our setups that could explain why the background handler isn't being triggered on iOS in my case.

Looking forward to your response!

kirya355 avatar Mar 21 '25 14:03 kirya355

Here’s the video: https://github.com/user-attachments/assets/0a86da73-070f-47a1-8c21-9d27c53d9f36

kirya355 avatar Mar 21 '25 14:03 kirya355

I downgraded the version to: firebase_messaging: 15.1.2

and now the background handler works again as usual.

With version: firebase_messaging: 15.2.4

the background handler does not work.

Tested on an iPhone 16 Pro iOS 18.4

b3nni97 avatar Mar 21 '25 14:03 b3nni97

@b3nni97 Thanks for sharing your solution! Unfortunately, in my case, it didn't work with the older version either. I tried using:

firebase_core: ^3.12.1 firebase_messaging: 15.1.2 with "Allow Non-modular includes in Framework Modules" set to YES

But the background handler still doesn't work for me.

I'm glad it worked for you with the downgraded version, but it seems there might be additional factors affecting this behavior. If anyone else has insights or alternative solutions, I'd appreciate hearing them!

Tested on iPhone 13 pro IOS 18.3.2

kirya355 avatar Mar 26 '25 09:03 kirya355

@kirya355 You have to make sure that you are using 15.1.2 in your pubspec.lock file.

b3nni97 avatar Mar 26 '25 15:03 b3nni97

I have a same issue, it's working fine on android but not working on iOS.

firebase_messaging: ^15.2.4

ziqq avatar Mar 27 '25 07:03 ziqq

Maybe it will save someone else’s day. For some freaking reason, I had FirebaseAppDelegateProxyEnabled set to NO, and according to Git, it always was — and everything had been working until yesterday.

beatread avatar Mar 27 '25 17:03 beatread

Unfortunately previous answer fixed for me onBackgroundMessage in debug but not release mode

beatread avatar Mar 27 '25 21:03 beatread

I have a same issue, it's working fine on android but not working on iOS onBackgroundMessage is never called in ios

evar-leeo avatar Mar 28 '25 07:03 evar-leeo

same problem on iOS onBackgroundMessage is never called

b4-tech avatar Mar 29 '25 11:03 b4-tech

I also encountered this issue. Do you know approximately when this problem can be resolved?

mhqihan avatar Mar 31 '25 10:03 mhqihan

Hi @SelaseKay I don’t know whether it will help solve the issue, but we are encountering it randomly. Some pushes trigger onBackgroundMessage, while others don’t, without any obvious reason. Each push is configured the same and contains identical content.

new MulticastMessage
{
 Notification = new Notification
 {
  Title = title,
  Body = messageText,
 },
 Data = data,
 Webpush = new WebpushConfig
 {
  Notification = new WebpushNotification
  {
   Body = messageText,
   Title = title,
   Silent = isSilent,
   Renotify = true
  },
 },
 Android = new AndroidConfig
 {
  FcmOptions = new AndroidFcmOptions
  {
   AnalyticsLabel = "push-android",
  },
  Notification = new AndroidNotification
  {
   Priority = isSilent ? NotificationPriority.MIN : NotificationPriority.MAX,
   Visibility = NotificationVisibility.PUBLIC,
   Sticky = true,
   DefaultLightSettings = true,
   DefaultSound = true,
   DefaultVibrateTimings = true,
   EventTimestamp = DateTime.UtcNow
  },
  Priority = Priority.High,
 },
 Apns = new ApnsConfig
 {
  FcmOptions = new ApnsFcmOptions
  {
   AnalyticsLabel = "push-ios"
  },
  Aps = new Aps
  {
   CriticalSound = new CriticalSound
   {
    Critical = !isSilent,
    Volume = isSilent ? 0.0 : 1.0,
    Name = "default"
   },
   ContentAvailable = true,
   MutableContent = true,
  },
 },
};

where isSilent always is false

beatread avatar Mar 31 '25 11:03 beatread

Having the same issue: FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler) is not being called when a notification is received in the background. Push notifications are working, but the listener is not functioning.

please provide solution ASAP

jgohilsigma avatar Apr 02 '25 11:04 jgohilsigma

For those who struggled by unstable background processing same as me. Our team investigated the issue, and so far found that the frequency is a key. Don't spam with content-available pushes. Always use reasonable frequency, at least a few minutes between each push. Also minimise daily amount of content-available pushes as possible. And last but not least, don't rely much on pushes in terminated state, try to avoid your app from being swiped out from the recents on iOS. So far it helps the most, but still can’t say that the problem is completely solved.

beatread avatar Apr 04 '25 11:04 beatread