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.7k stars 3.97k forks source link

🐛 [firebase_messaging] iOS Notifications not received in 8.0.0-dev.8 #4097

Closed paynekw closed 3 years ago

paynekw commented 3 years ago

Bug report

Describe the bug

After upgrading to 8.0.0-dev.8 from 7.0.3, iOS does not receive/respond to push notifications i.e. no handlers or events fire. With 7.0.3, foreground notifications were working but not background notifications, which is the reason for upgrading to 8.x.

Android is fine whether in foreground or background, or terminated. Trace information from iOS shows that initialization succeeds without error. The iOS trace is the same as that from Android and shows no irregularities. iOS Requests permission, which I grant. Settings reports that all permissions are granted as expected.

I'm using an iPhone 6 physical device running iOS 12.4.9 and the flutter_local_notifications plugin. APNs is configured with a .p8 Authentication Key. When I send a notification via FCM to the iPhone, the response reports success with success: 1, failure: 0 and a valid message_id.

Steps to reproduce

Steps to reproduce the behavior:

  1. Install and configure the firebase_messaging: ^8.0.0-dev.8 plugin as per documentation and examples.
  2. Send a push notification to an iPhone via FCM.

Expected behavior

One of [FirebaseMessaging.onMessage, FirebaseMessaging.onBackgroundMessage, FirebaseMessaging.onMessageOpenedApp] should fire. I've added trace information to each handler and it appears that they are never invoked on iOS. As mentioned earlier, all work as expected in Android.


Additional context

AppDelegate.swift includes:

    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
    }

Info.plist includes:

    <key>FirebaseAppDelegateProxyEnabled</key>
    <false/>
    <key>UIBackgroundModes</key>
    <array>
        <string>fetch</string>
        <string>processing</string>
        <string>remote-notification</string>
    </array>

I have tried various things to enable/disable method swizzling and also with/without the entry in info.plist. The setting appears to have no effect.

project.pbxproj includes:

/* Begin PBXProject section */
        97C146E61CF9000F007C117D /* Project object */ = {
            isa = PBXProject;
            attributes = {
                LastUpgradeCheck = 1020;
                ORGANIZATIONNAME = "**************";
                TargetAttributes = {
                    97C146ED1CF9000F007C117D = {
                        CreatedOnToolsVersion = 7.3.1;
                        DevelopmentTeam = **********;
                        LastSwiftMigration = 1100;
                        SystemCapabilities = {
                            com.apple.BackgroundModes = {
                                enabled = 1;
                            };
                            com.apple.Push = {
                                enabled = 1;
                            };
                        };
                    };
                };

I believe I do not require an entitlements file with CODE_SIGN_ENTITLEMENTS pointing to it to specify the aps-environment, because FCM is configured with a .p8 key and not environment-specific certificates.

Sending notifications

I have tried with/without and all possible values for priority and content-available when sending the notification via FCM without any observable change in behavior.


Flutter doctor

Run flutter doctor and paste the output below:

Click To Expand ``` [√] Flutter (Channel stable, 1.22.3, on Microsoft Windows [Version 10.0.19041.610], locale en-GI) • Flutter version 1.22.3 at ... • Framework revision 8874f21e79 (13 days ago), 2020-10-29 14:14:35 -0700 • Engine revision a1440ca392 • Dart version 2.10.3 [√] Android toolchain - develop for Android devices (Android SDK version 30.0.2) • Android SDK at ... • Platform android-30, build-tools 30.0.2 • Java binary at: ... • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01) • All Android licenses accepted. [√] Android Studio (version 3.6) • Android Studio at ... • Flutter plugin version 46.0.1 • Dart plugin version 192.8052 • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04) [!] Android Studio (version 4.1.0) • Android Studio at ... X Flutter plugin not installed; this adds Flutter specific functionality. X Dart plugin not installed; this adds Dart specific functionality. • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01) [√] Connected device (1 available) • Android SDK built for x86 (mobile) • emulator-5554 • android-x86 • Android 10 (API 29) (emulator) ! Doctor found issues in 1 category. ``` I run multiple versions of Android Studio side-by-side, so ignore the incorrect warnings about the Dart and Flutter plugins not being installed in 4.x (they most certainly are.)

Flutter dependencies

Run flutter pub deps -- --style=compact and paste the output below:

Click To Expand ``` dependencies: - bcv_domain 0.0.0 [bcv_global intl decimal] - bcv_global 0.0.0 [intl decimal uuid] - carousel_slider 2.3.1 [flutter] - charts_flutter 0.9.0 [charts_common collection flutter intl logging meta] - contacts_service 0.4.6 [flutter collection quiver] - decimal 0.3.5 [rational] - file_picker 2.0.0 [flutter flutter_web_plugins flutter_plugin_android_lifecycle plugin_platform_interface] - firebase_core 0.5.2 [firebase_core_platform_interface flutter quiver meta firebase_core_web] - firebase_messaging 8.0.0-dev.8 [meta flutter firebase_core firebase_core_platform_interface firebase_messaging_platform_interface] - flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine] - flutter_local_notifications 3.0.1+2 [flutter platform flutter_local_notifications_platform_interface timezone] - geolocator 6.1.6 [flutter geolocator_platform_interface] - google_sign_in 4.5.6 [google_sign_in_platform_interface flutter meta google_sign_in_web] - http 0.12.2 [http_parser path pedantic] - image_picker 0.6.7+14 [flutter flutter_plugin_android_lifecycle image_picker_platform_interface] - intl 0.16.1 [path] - numberpicker 1.2.1 [flutter infinite_listview] - package_info 0.4.3+2 [flutter] - permission_handler 5.0.1+1 [flutter meta permission_handler_platform_interface] - photo_view 0.10.2 [flutter] - qr_flutter 3.2.0 [flutter qr] - shared_preferences 0.5.12+4 [meta flutter shared_preferences_platform_interface shared_preferences_linux shared_preferences_macos shared_preferences_web shared_preferences_windows] - validators 2.0.1 [vin_decoder] - wc_flutter_share 0.2.2 [flutter path_provider] dev dependencies: - flutter_launcher_icons 0.7.5 [image args yaml] - flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher meta source_span stream_channel string_scanner term_glyph typed_data] - pedantic 1.9.2 [meta] transitive dependencies: - archive 2.0.13 [crypto args path] - args 1.6.0 - asn1lib 0.6.5 - async 2.5.0-nullsafety.1 [collection] - basic_utils 2.6.3 [http logging json_annotation pointycastle asn1lib convert crypto] - boolean_selector 2.1.0-nullsafety.1 [source_span string_scanner] - characters 1.1.0-nullsafety.3 - charcode 1.2.0-nullsafety.1 - charts_common 0.9.0 [collection intl logging meta vector_math] - clock 1.1.0-nullsafety.1 - collection 1.15.0-nullsafety.3 - convert 2.1.1 [charcode typed_data] - crypto 2.1.5 [collection convert typed_data] - fake_async 1.2.0-nullsafety.1 [clock collection] - ffi 0.1.3 - file 5.2.1 [intl meta path] - firebase_core_platform_interface 2.0.0 [flutter meta plugin_platform_interface quiver] - firebase_core_web 0.2.1 [firebase_core_platform_interface flutter flutter_web_plugins meta js] - firebase_messaging_platform_interface 1.0.0-dev.5 [flutter meta firebase_core plugin_platform_interface] - flutter_local_notifications_platform_interface 2.0.0 [flutter plugin_platform_interface] - flutter_plugin_android_lifecycle 1.0.11 [flutter] - flutter_web_plugins 0.0.0 [flutter characters collection meta typed_data vector_math] - geolocator_platform_interface 1.0.8 [flutter meta plugin_platform_interface vector_math] - google_sign_in_platform_interface 1.1.2 [flutter meta quiver] - google_sign_in_web 0.9.2 [google_sign_in_platform_interface flutter flutter_web_plugins meta js] - http_parser 3.1.4 [charcode collection source_span string_scanner typed_data] - image 2.1.18 [archive xml meta] - image_picker_platform_interface 1.1.1 [flutter meta http plugin_platform_interface] - infinite_listview 1.0.1+1 [flutter] - js 0.6.2 - json_annotation 3.0.1 - logging 0.11.4 - matcher 0.12.10-nullsafety.1 [stack_trace] - meta 1.3.0-nullsafety.3 - path 1.8.0-nullsafety.1 - path_provider 1.6.24 [flutter path_provider_platform_interface path_provider_macos path_provider_linux path_provider_windows] - path_provider_linux 0.0.1+2 [path xdg_directories path_provider_platform_interface flutter] - path_provider_macos 0.0.4+6 [flutter] - path_provider_platform_interface 1.0.4 [flutter meta platform plugin_platform_interface] - path_provider_windows 0.0.4+3 [path_provider_platform_interface meta path flutter ffi win32] - permission_handler_platform_interface 2.0.1 [flutter meta plugin_platform_interface] - petitparser 3.1.0 [meta] - platform 2.2.1 - plugin_platform_interface 1.0.3 [meta] - pointycastle 1.0.2 - process 3.0.13 [file intl meta path platform] - qr 1.3.0 [meta] - quiver 2.1.5 [matcher meta] - random_string 2.1.0 - rational 0.3.8 - shared_preferences_linux 0.0.2+4 [file flutter meta path path_provider_linux shared_preferences_platform_interface] - shared_preferences_macos 0.0.1+11 [shared_preferences_platform_interface flutter] - shared_preferences_platform_interface 1.0.4 [meta flutter] - shared_preferences_web 0.1.2+7 [shared_preferences_platform_interface flutter flutter_web_plugins meta] - shared_preferences_windows 0.0.1+3 [shared_preferences_platform_interface flutter ffi file meta path path_provider_platform_interface path_provider_windows] - sky_engine 0.0.99 - source_span 1.8.0-nullsafety.2 [charcode collection path term_glyph] - stack_trace 1.10.0-nullsafety.1 [path] - stream_channel 2.1.0-nullsafety.1 [async] - string_scanner 1.1.0-nullsafety.1 [charcode source_span] - term_glyph 1.2.0-nullsafety.1 - test_api 0.2.19-nullsafety.2 [async boolean_selector collection meta path source_span stack_trace stream_channel string_scanner term_glyph matcher] - timezone 0.5.9 [path] - typed_data 1.3.0-nullsafety.3 [collection] - uuid 2.2.2 [crypto convert] - vector_math 2.1.0-nullsafety.3 - vin_decoder 0.1.2 [meta basic_utils http random_string] - win32 1.7.3 [ffi] - xdg_directories 0.1.2 [meta path process] - xml 4.5.1 [collection convert meta petitparser] - yaml 2.2.1 [charcode collection string_scanner source_span] ```

The frustrating part is that I do not have XCode or a Mac. Each cloud build takes around 20 minutes, and costs money. I haven't ruled out the possibility of the XCode project configuration being slightly incomplete/incorrect due to not having access to XCode, however I have tried everything I can think of, and have run out of resources providing hints as to what the problem might be.

So far, two full days have been spent trying to get this to work.

Haldlugal commented 3 years ago

Hello! There is a problem with typization when creating a RemoteMessage from data that is received from push notification on ios. data argument should be <String, dynamic>, not <String, String>, as I understand. For example, that is data that I receive in my Push on Ios: data: {fcm_options: {image: https://images-na.ssl-images-amazon.com/images/I/81-yKbVND-L._SY355_.png}, test: test} Flutter don't like such typization and throws an Error that isn't handled anywhere.

markusaksli-nc commented 3 years ago

I can't reproduce this with just the official example on firebase_messaging: ^8.0.0-dev.8 on the latest flutter master 1.24.0-8.0.pre.208.

flutter doctor -v ``` [✓] Flutter (Channel master, 1.24.0-8.0.pre.208, on Mac OS X 10.15.7 19H2 darwin-x64, locale en-GB) • Flutter version 1.24.0-8.0.pre.208 at /Users/markus/development/flutter_master • Framework revision 15d2d8a875 (8 hours ago), 2020-11-11 20:04:03 -0500 • Engine revision d97a81c889 • Dart version 2.12.0 (build 2.12.0-31.0.dev) [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.1) • Android SDK at /Users/markus/Library/Android/sdk • Platform android-30, build-tools 30.0.1 • Java binary at: /Users/markus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6858069/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 12.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 12.1, Build version 12A7403 • CocoaPods version 1.10.0 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 4.1) • Android Studio at /Users/markus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6858069/Android Studio.app/Contents • Flutter plugin can be installed from: � https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: � https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) [✓] Connected device (5 available) • Nevercode’s iPhone (mobile) • b668e524315069f3db3661ac11ff1f66afafebdb • ios • iOS 14.1 • iPhone 12 Pro Max (mobile) • 1C7EE787-1EC9-427C-AFEE-224EF736BBCA • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-1 (simulator) • macOS (desktop) • macos • darwin-x64 • Mac OS X 10.15.7 19H2 darwin-x64 • Web Server (web) • web-server • web-javascript • Flutter Tools • Chrome (web) • chrome • web-javascript • Google Chrome 86.0.4240.193 ! Error: Nevercode’s iPhone is busy: Copying cache files from device. Xcode will continue when Nevercode’s iPhone is finished. (code -10) • No issues found! ```

Everything works fine on both Android and iOS. From the sounds of it it could be an Xcode config issue. The official steps for configuring the Xcode project and APN is at FCM via APNs Integration.

Have you followed these steps? I wouldn't expect notifications to work without this.

paynekw commented 3 years ago

@markusaksli-nc I followed the configuration steps carefully, and as mentioned in the bug report iOS notifications were working great in version 7.0.3.

After migrating to ^8.0.0-dev.8 iOS went completely dead without any changes to the XCode, Apple, or FCM configuration, so although I said I haven't completely ruled out XCode configuration, I am reluctant to believe that it's a configuration issue.

Firebase reports success when sending a notification. If there's a problem it typically responds with failure and a reason e.g. "not registered", "authentication error", etc.

Can you confirm that it all works on Flutter stable channel, as I saw you tested against master?

markusaksli-nc commented 3 years ago

It works on stable as well for me.

If the notifications reach the device but the callbacks are not triggered, could you try to see if there is any useful output with flutter run -v or in Xcode console?

paynekw commented 3 years ago

Thank you for testing on stable channel.

I needed a sanity check to ensure that something on the Apple/Firebase side hadn't changed or gone foul, so I went back to using package 7.0.3 and once again I am receiving notifications on iOS.

I don't have a Mac with XCode, and so cannot get closer to the internal logs or output. What I did was embed debug code everywhere to emit trace information to a REST API for logging. The trace tells me that either the device isn't receiving notifications (unlikely, because using 7.0.3 they are received) or the callbacks aren't being fired (trace shows nothing whatsoever emitted when using 8.x).

I see everything initialize OK and without error. Both devices register with Firebase, because the notification sends OK. If the device didn't register, the error message in the response is NotRegistered.

Something's gone a bit wack somewhere on the iOS side I think, that isn't causing a problem in your canonical example. I'm unclear as to whether the delegate assignment in AppDelegate.swift is still needed (8.x change log says no, then yes, then maybe no).

Perhaps the previous issue with co-existing with other plugins e.g. flutter_local_notifications has resurfaced.

I don't really know what to try next.

Den-Ree commented 3 years ago

Have the same problem on iOS

diegogarciar commented 3 years ago

On my side its not working when including the content-available flag, I think the didReceiveRemoteNotification its not sending the message to flutter

paynekw commented 3 years ago

Everyone, please share the iOS version running on your phones. I believe this issue may be iOS version-specific. In #4096 it's working on 14.2.

From what I have read, didReceiveRemoteNotification is legacy support for versions < 10.

The documentation for content-available is misleading. In some places I've read that content-available is to force a silent, background-only message, so that app can update its content in the background. The package documentation states that content-available: true will force a high-priority notification. Nowhere does it say whether the value should be a bool or a string.

Den-Ree commented 3 years ago

@paynekw I was using iOS 14.1, now updating to iOS 14.2. I will do testing and return back with results.

diegogarciar commented 3 years ago

same as @Den-Ree I might wait for Xcode 12.2 official release though. @paynekw I normally use "content-available" : 1 and it works.

I mentioned about didReceiveRemoteNotification as I debugged this in the code

 if (notification.request.content.userInfo[@"gcm.message_id"]) {
    NSDictionary *notificationDict =
        [FLTFirebaseMessagingPlugin NSDictionaryFromUNNotification:notification];

    // Don't send an event if contentAvailable is true - application:didReceiveRemoteNotification
    // will send the event for us, we don't want to duplicate them.
    if (!notificationDict[@"contentAvailable"]) {
      [_channel invokeMethod:@"Messaging#onMessage" arguments:notificationDict];
    }
  }

So I was seeing how the last line was working but skipped when I included content-available, didReceiveRemoteNotification was never called when adding content-available.

furkankurt commented 3 years ago

Same problem here, on iOS 14.2 I cannot receive the notifications at all.

diegoveloper commented 3 years ago

I'm on iOS 13.5.2, push notifications with notification payload are received but I'm not receiving push without the payload. I want to receive silent notifications but it doesn't work, I'm testing from console.

DATA='{"content-available": true, "data": {"badge": 10, "click_action": "FLUTTER_NOTIFICATION_CLICK", "id": "34331"}, "to": "my_token"}'
curl https://fcm.googleapis.com/fcm/send -H "Content-Type:application/json" -X POST -d "$DATA" -H "Authorization: key=my_key" -H "apns-push-type: background"

anything wrong?

markusaksli-nc commented 3 years ago

I updated to iOS 14.2 on my physical and Xcode to 12.2, and prefromed a fresh install but notifications still work as expected with the official example on 1.24.0-8.0.pre.229 with

  firebase_core: ^0.5.2
  firebase_messaging: ^8.0.0-dev.8
  flutter_local_notifications: ^3.0.1+2
  http: ^0.12.2
flutter doctor -v ``` [✓] Flutter (Channel master, 1.24.0-8.0.pre.229, on Mac OS X 10.15.7 19H2 darwin-x64, locale en-GB) • Flutter version 1.24.0-8.0.pre.229 at /Users/markus/development/flutter_master • Framework revision 7cda6866b0 (10 hours ago), 2020-11-12 22:39:02 -0500 • Engine revision dddb532b5c • Dart version 2.12.0 (build 2.12.0-37.0.dev) [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.1) • Android SDK at /Users/markus/Library/Android/sdk • Platform android-30, build-tools 30.0.1 • Java binary at: /Users/markus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6858069/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 12.2) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 12.2, Build version 12B45b • CocoaPods version 1.10.0 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 4.1) • Android Studio at /Users/markus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6858069/Android Studio.app/Contents • Flutter plugin can be installed from: � https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: � https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) [✓] Connected device (4 available) • Nevercode’s iPhone (mobile) • b668e524315069f3db3661ac11ff1f66afafebdb • ios • iOS 14.2 • macOS (desktop) • macos • darwin-x64 • Mac OS X 10.15.7 19H2 darwin-x64 • Web Server (web) • web-server • web-javascript • Flutter Tools • Chrome (web) • chrome • web-javascript • Google Chrome 86.0.4240.193 • No issues found! ```

I'm going to label this issue anyway due to the amount of comments but everybody please make sure you have followed FCM via APNs Integration closely.

diegoveloper commented 3 years ago

@markusaksli-nc did you try with silent notifications?

markusaksli-nc commented 3 years ago

@diegoveloper Works for me

Payload ``` { "content_available": true, "data": { "badge": 10, "click_action": "FLUTTER_NOTIFICATION_CLICK", "id": 34331 }, "to": "" } ```
curl https://fcm.googleapis.com/fcm/send -H "Content-Type:application/json" -X POST -d @send.json -H "Authorization: key=<key>"
flutter: {messageId: 1605277313184085, data: {id: 34331, badge: 10, click_action: FLUTTER_NOTIFICATION_CLICK}, contentAvailable: true}
flutter: Handling a background message 1605277151756920
diegoveloper commented 3 years ago

@markusaksli-nc ah wait, content_available vs content-available , I was checking the documentation from: https://firebase.flutter.dev/docs/messaging/usage/ , is the doc wrong ?

Screen Shot 2020-11-13 at 9 28 49 AM

btw I'm talking about silent pushes in iOS

markusaksli-nc commented 3 years ago

It isn't wrong since it is the name of the APN payload parameter, that guide is more for the dart code usage of the flutter plugin.

I'd refer to the official FCM HTTP Ref for sending notifications through FCM.

content_available | Optional, boolean | On iOS, use this field to represent content-available in the APNs payload.

diegoveloper commented 3 years ago

@markusaksli-nc okay, did you try silent push in iOS?

markusaksli-nc commented 3 years ago

@diegoveloper The payload and curl request I posted are for a silent push in iOS. The payload is recieved but there is no notification, as shown by the print logs.

diegoveloper commented 3 years ago

@markusaksli-nc for me it's only working on Android :/ , on iOS I can't receive the silent push. Maybe it's something related to iOS version.

These is my info:

Flutter Channel stable, 1.22.3 iOS version 13.5.2

diegogarciar commented 3 years ago

I'm getting this error when on the Xcode logs when I send a notification with content-available, which I believe is handled as a data message.

Warning: Application delegate received call to -application:didReceiveRemoteNotification:fetchCompletionHandler: but the completion handler was never called.

I'm setting a breakpoint at

#if !TARGET_OS_OSX
- (BOOL)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {

but its seems its never called, I indeed was missing the background-fetch capability, but its still supposed to work when the app is in foreground.

paynekw commented 3 years ago

@diegogarciar in your case, the reason the completion handler is not called might be because:

  /// Callback for handling when a notification is triggered while the app is
  /// in the foreground.
  ///
  /// This property is only applicable to iOS versions older than 10.
  final DidReceiveLocalNotificationCallback onDidReceiveLocalNotification;
diegogarciar commented 3 years ago

yes but that's LOCAL callback, I'm debugging the REMOTE callback

optional func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

Use this method to process incoming remote notifications for your app. Unlike the application(_:didReceiveRemoteNotification:) method, which is called only when your app is running in the foreground, the system calls this method when your app is running in the foreground or background. In addition, if you enabled the remote notifications background mode, the system launches your app (or wakes it from the suspended state) and puts it in the background state when a remote notification arrives.

spalenzuela commented 3 years ago

@markusaksli-nc I run example app but onBackgroundMessage not working in iOS 14.1

@diegoveloper Works for me

Payload

curl https://fcm.googleapis.com/fcm/send -H "Content-Type:application/json" -X POST -d @send.json -H "Authorization: key=<key>"
flutter: {messageId: 1605277313184085, data: {id: 34331, badge: 10, click_action: FLUTTER_NOTIFICATION_CLICK}, contentAvailable: true}
flutter: Handling a background message 1605277151756920
DFelten commented 3 years ago

Same issue here. When adding an image fcm_options is added to the data field in messageMap automatically. A crash appears in RemoteMessage.fromMap(messageMap) when trying to parse the data to Map<String, String>.

When changing Map<String, String>.from(map['data']) to Map<String, dynamic>.from(map['data']) and final Map<String, dynamic> data; it works.

timruddell commented 3 years ago

I'm having a similar issue - in my case it appears that the sentTime field is being provided as a String instead of an int. I've changed the following in RemoteMessage.fromMap:

From:

sentTime: map['sentTime'] == null ? null : DateTime.fromMillisecondsSinceEpoch(map['sentTime']),

To:

sentTime: map['sentTime'] == null ? null : DateTime.fromMillisecondsSinceEpoch(int.parse(map['sentTime'].toString())),

DFelten commented 3 years ago

I created a pull request (https://github.com/FirebaseExtended/flutterfire/pull/4150) for the wrong mapping of the data attribute of RemoteMessage.

Salakar commented 3 years ago

Thanks @DFelten for the PR, I've updated it to also cover the issue mentioned by @timruddell above and this has now been merged. Will publish another dev release shortly

markusaksli-nc commented 3 years ago

After updating to Big Sur and reinstalling Xcode I started getting this as well (did not change the app itself during this).

FCM says "success":1,"failure":0 but nothing is received on the target phone using the latest master 1.24.0-8.0.pre.304 with firebase_messaging: ^8.0.0-dev.8.

flutter doctor -v ``` [✓] Flutter (Channel master, 1.24.0-8.0.pre.304, on macOS 11.0.1 20B29 darwin-x64, locale en-GB) • Flutter version 1.24.0-8.0.pre.304 at /Users/markus/development/flutter_master • Framework revision c6290500f8 (12 hours ago), 2020-11-18 17:29:28 -0800 • Engine revision 35a0b9fe68 • Dart version 2.12.0 (build 2.12.0-50.0.dev) [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.1) • Android SDK at /Users/markus/Library/Android/sdk • Platform android-30, build-tools 30.0.1 • Java binary at: /Users/markus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6953283/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 12.2) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 12.2, Build version 12B45b • CocoaPods version 1.10.0 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 4.1) • Android Studio at /Users/markus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6953283/Android Studio.app/Contents • Flutter plugin can be installed from: � https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: � https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495) [✓] Connected device (4 available) • Nevercode’s iPhone (mobile) • b668e524315069f3db3661ac11ff1f66afafebdb • ios • iOS 14.2 • macOS (desktop) • macos • darwin-x64 • macOS 11.0.1 20B29 darwin-x64 • Web Server (web) • web-server • web-javascript • Flutter Tools • Chrome (web) • chrome • web-javascript • Google Chrome 87.0.4280.67 • No issues found! ```

Doesn't seem like this has anything to do with the PR issues since I'm using a very basic payload

Payload ```json { "notification": { "body": "this is a body", "title": "this is a title" }, "priority": "high", "data": {}, "to": "FCM Token" } ```
Johann673 commented 3 years ago

I have the same issue with silent message (only with "data") Finally, i juste change contentAvailable: true by content_available: true and now my silent message works great again !

xlcod commented 3 years ago

I have the same issue with silent message (only with "data") Finally, i juste change contentAvailable: true by content_available: true and now my silent message works great again ! @Johann673 on the firebase console as a data ?

markusaksli-nc commented 3 years ago

dev.9 seems to have fixed the issues for me, receiving everything properly again.

paynekw commented 3 years ago

I'm releasing a build today and will report findings using dev.9 soon

diegogarciar commented 3 years ago

Heres what I tested out for dev.9

"content-available": 0 Background: Notification shows Foreground: onMessage gets called summary: working as expected

"content-available": 1 Background: Notifications shows, onBackgroundMessage not called Foreground: onMessage is not called summary: flutter is completely dead when using content-available

btw, firebase.flutter.dev docs are incorrect in this example

 apns: {
      payload: {
        aps: {
          contentAvailable: true,
          sound: 'default',
        },
      },
    },

it is not contentAvailable, it is content-available as per apple's documentation

so if you're trying with contentAvailable, you are receiving a normal notification and that's why its working

paynekw commented 3 years ago

I'm afraid to say that iOS is still completely dead for me on dev.9

paynekw commented 3 years ago

I have a few things on my mind.

  1. When looking at and following the instructions here, the screen cast clearly shows uploading of a .p8 key and the absence of APNs environment-specific certificates. According to the instructions, a .p8 key being uploaded is all that is required - it's apparently APNs environment-agnostic.

  2. When looking at the example project, I see that it enforces code signing an .entitlements file to specify the aps-environment.

  3. When I do the same and sign an .entitlements file, but without having environment-specific certificates configured, the build succeeds, but I get a runtime error when sending a notification, and the error is InvalidCredential, which is expected, as I have not configured a certificate for the designated environment.

  4. Therefore, as I understand it, a .p8 key and code-signing environment-specific certificates are mutually exclusive. You either use a .p8 key, or you code-sign an .entitlements file pointing to a certificate, specific to the environment specified in the .entitlements file.

Questions:

  1. If the instructions demonstrate that all that is required is to use a .p8 key, but the example project is signing an .entitlements file, and .p8 and .entitlements appear to be mutually exclusive, what is the example app actually using?

AFAIK there's no way to upload a .p8 and also configure environment-specific certificates in Firebase Messaging. I might be wrong, but I tried and it appears to be either one or the other.

TL;DR

I don't understand (forgive me) how the example project can be configured as per the instructions to use a .p8 key only, and also work with a code-signed .entitlements file, unless somehow in the past someone loaded APNs certificates or something locally into Xcode which is overriding the general configuration.

I'd like to see this tested being built in the Cloud and not just locally.

EDIT: I never receive InvalidCredential with my current setup using .p8.

Salakar commented 3 years ago

it is not contentAvailable, it is content-available as per apple's documentation

so if you're trying with contentAvailable, you are receiving a normal notification and that's why its working

This is not correct. contentAvailable in that example IS correct - this is the TypeScript/JS name defined in the Firebase Admin SDK for Node.js. It's not the APNS http api name. https://github.com/firebase/firebase-admin-node/blob/master/src/messaging/index.ts#L331

Salakar commented 3 years ago
  1. If the instructions demonstrate that all that is required is to use a .p8 key, but the example project is signing an .entitlements file, and .p8 and .entitlements appear to be mutually exclusive, what is the example app actually using?

The .p8 is for server code and is not for Xcode and has no direct relation to the entitlements / profile for Xcode in this context.

Specifying the Team ID on the Firebase Console when uploading the .p8 is how the two can be connected. The Firebase Console/backend can read provisioned profiles/app ids from an Apple API using the .p8 and based on your Firebase iOS Bundle Identifier (defined when creating your iOS app on the Firebase Console) pair this up with a provisioning profile that has the APNs entitlement where the App Id matches the Bundle ID.

aytunch commented 3 years ago

@diegogarciar were you able to get onBackgroundMessage callback to run in all cases? I am having problems with iOS. The operating systems shows a banner while app is in the background but onBackgroundMessage does not fire no matter what I send

diegogarciar commented 3 years ago

@aytunch no, it seems that optional func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

is still not being called when using contentAvailable. And that function is in charge of calling either onBackgroundMessage or onMessage based on background state.

aytunch commented 3 years ago

@diegogarciar thanks for the quick response. I understand that the problem is being caused by the native iOS code. Not from the Flutter side. However in my case I am sending a Data&Notification message, not an only Data message. So content-available should not be relevant for my case. onBackgroundMessage should fire automatically. @Salakar Can you please confirm if this is a bug or not and fix the native side accordingly?

diegogarciar commented 3 years ago

@aytunch onBackgroundMessage is sent to flutter only from that iOS function, so if that function is not working, it will fail for all message types.

PD: I'm also using Data&Notification message.

carlos-labrador commented 3 years ago

I have the same issue with silent message (only with "data") Finally, i juste change contentAvailable: true by content_available: true and now my silent message works great again !

It works for me, thanks.

vanlooverenkoen commented 3 years ago

I am not receiving push notifications on my iOS simulators. starting from 8.x.x In 7.0.3 I was able to receive push notifications when the app was open. when the app is closed no push notifications will be received as expected. But after upgrading to 8.x.x I am not receiving any push notifications on my iOS simulators. Real device works fine.

Why is this changed in the new version?

After some testing I saw that my apns token was null on a simulator and not null on a real device. How is it possible that I received notification in the old version but not in the new release?

Right now I am using 8.0.0-dev.11

paynekw commented 3 years ago

@vanlooverenkoen I believe the root cause was discovered in #4388, and we're now waiting on #4412. I seem to recall reading in the documentation that notifications don't work in simulator by default. There may be a way to test notifications in simulator, but I believe the default behavior is that they don't - a physical device is required.

vanlooverenkoen commented 3 years ago

@paynekw a physical device is indeed required if the app is killed so the notifications are shown in the notification tray. On 7.0.3 we were able to develop our app in the simulator with the notification updates. But only while the app was open. (as expected). If I switch back to version 7.0.3 the notifications still work. but we are required to upgrade to 8.x.x because of the v2 embedding for android. So you can already see the problem.

We cannot use v1 because we need the functionality of v2 for another part of our app. and v2 is breaking the firebase_messaging op iOS

I saw that issue as well. But I am not using firebase_auth. We are only using firebase_core & firebase_messaging.

paynekw commented 3 years ago

@vanlooverenkoen in that case, I'm sorry I can't answer your specific question. There appear to be many having a variety of issues in various situations with 8.x. I myself have been unable to receive notifications since the beginning of November.

jamesblasco commented 3 years ago

I managed to solve this issue that was affected by the auth package. I am not having problems so far after this change https://github.com/FirebaseExtended/flutterfire/issues/4412#issuecomment-759628340

Salakar commented 3 years ago

In 7.0.3 I was able to receive push notifications when the app was open

On 7.0.3 we were able to develop our app in the simulator with the notification updates. But only while the app was open.

Yes correct as v7 used a now deprecated & removed feature from the underlying Firebase iOS SDK for messaging - a direct channel connection. The old Firebase iOS SDK could establish a direct connection to the FCM backend and receive messages bypassing the need for APNs whilst the app was open. This feature no longer exists, everything MUST now go through APNs - so you need to ensure you've set it up correctly.

I can't speak as to why it was removed but from my experience it's probably for the best, now you must setup APNs and if you don't do it correctly then you won't get any notifications, rather than the possibly confusing 'it works in the foreground but not in the background' issues (there's so many of these issues that have been made on FlutterFire and also over at React Native Firebase).

paynekw commented 3 years ago

I don't know whether #4657 fixed everyone else's problems, but after updating packages and dependencies, following this migration guide, revisiting all setup & configuration instructions, examining change logs etc., iOS is still completely dead for me.

Test notifications from Firebase Console aren't received on iOS, and the (legacy) REST endpoint continues to report success with no delivery to the device.

I give up. Am going to find an alternative to FCM because this has been a nightmare.

Thank you to the maintainers and the community who have been helpful.