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

🐛 [firebase_messaging] On Android, opening 21st or older notification cannot access data payload #12111

Closed amandaoneal closed 8 months ago

amandaoneal commented 8 months ago

Bug report

My server sends Firebase notifications (notification+data). My app uses the data to decide what to do after the notification is clicked by the user. In most cases, it works correctly: user clicks notification, my app gets the data (either through FirebaseMessaging.instance.getInitialMessage if terminated, or onMessageOpenedApp's RemoteMessage parameter if backgrounded). But in one specific case: on Android, if the notification is the 21st or older notification, this flow fails. Clicking the notification opens my app, but getInitialMessage is null, and onMessageOpenedApp is NOT called.

Steps to reproduce

Steps to reproduce the behavior:

  1. Set up an app with onMessageOpenedApp, as well as a call to FirebaseMessaging.instance.getInitialMessage() within your app's init functions. Example:

    @override
    void initState() {
      super.initState();
      print("TEST 1");
      RemoteMessage? initialMessage =
          await FirebaseMessaging.instance.getInitialMessage();
      if (initialMessage != null) {
        print("TEST 2");
      }
    
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print("TEST3");
    });
    }
  2. Send twenty-two (22) (or more) Firebase notifications, each with both data and notification. (The app should be backgrounded on the phone when these are sent). Example based on my code (Python):

    data = {
        'url_fragment' : 'something',
        'title' : 'something',
        'body' : 'something',
        'click_action' : 'FLUTTER_NOTIFICATION_CLICK',
        'android_channel_id' : 'something'
        }
    
    androidNotification = messaging.AndroidNotification(title='something', body='something', channel_id='something')
    androidConfig = messaging.AndroidConfig(notification=androidNotification)
    message = messaging.Message(data=data, topic=androidtopic, android=androidConfig)
    response = messaging.send(message)
  3. Note that the notifications DO successfully show up in the device's notification tray.
  4. Force-close the app (swipe up from app list).
  5. Click the OLDEST notification - the one that was sent first of the 22. (You may have to swipe away a few to get to it). Note that in the above code, TEST 1 prints, but TEST 2 doesn't, meaning it called getInitialMessage() but the return value was null. This shouldn't be the case. (Note you can use adb logcat to watch print statements when launching from terminated)
  6. Now that the app is open, click the SECOND-OLDEST notification - the one that was sent second of the 22. Note that in the code above, TEST 3 doesn't print, meaning onMessageOpenedApp() wasn't called, even though it should have been.

Expected behavior

getInitialMessage() and onMessageOpenedApp() should return the correct data for a message, even if 20+ notifications have been sent after it.


Additional context

To reiterate, this all works perfectly fine on iOS, and works perfectly fine on Android if there have been 19 or fewer notifications sent since the notification in question. This has been reported by my users to be happening on multiple versions of Android OS, and on different types of Android devices, so it's not specific to a particular Android setup, to my knowledge.

I will also note that my app only sends notifications when users request them - but it's fairly common for a user to want to receive 20+ notifications before clicking any of them. I'm not spamming anyone - I'm notifying them for specific events that they requested notifications for.


Flutter doctor

Run flutter doctor and paste the output below:

Click To Expand ``` Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 3.16.5, on macOS 14.2.1 23C71 darwin-x64, locale en-US) [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) [✓] Xcode - develop for iOS and macOS (Xcode 15.1) [✓] Chrome - develop for the web [✓] Android Studio (version 2022.2) [✓] VS Code (version 1.85.0) [✓] Connected device (4 available) [✓] Network resources • No issues found! ```

Flutter dependencies

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

Click To Expand ``` Dart SDK 3.2.3 Flutter SDK 3.16.5 alerts_for_reddit 3.1.1+27 dependencies: - app_settings 5.1.1 [flutter plugin_platform_interface] - cloud_kit 1.1.0 [flutter] - connectivity 3.0.6 [flutter meta connectivity_platform_interface connectivity_macos connectivity_for_web] - cupertino_icons 1.0.5 - device_info_plus 9.1.1 [device_info_plus_platform_interface ffi file flutter flutter_web_plugins meta win32 win32_registry] - file 6.1.4 [meta path] - firebase_core 2.24.2 [firebase_core_platform_interface firebase_core_web flutter meta] - firebase_messaging 14.7.9 [firebase_core firebase_core_platform_interface firebase_messaging_platform_interface firebase_messaging_web flutter meta] - flutter 0.0.0 [characters collection material_color_utilities meta vector_math web sky_engine] - flutter_local_notifications 16.3.0 [clock flutter flutter_local_notifications_linux flutter_local_notifications_platform_interface timezone] - html_unescape 2.0.0 - http 1.1.2 [async http_parser meta web] - in_app_review 2.0.8 [flutter in_app_review_platform_interface] - intl 0.19.0 [clock meta path] - oauth2 2.0.2 [collection crypto http http_parser] - purchases_flutter 6.5.1 [flutter freezed_annotation json_annotation] - shared_preferences 2.2.1 [flutter shared_preferences_android shared_preferences_foundation shared_preferences_linux shared_preferences_platform_interface shared_preferences_web shared_preferences_windows] - uni_links 0.5.1 [flutter uni_links_platform_interface uni_links_web] - url_launcher 6.1.14 [flutter url_launcher_android url_launcher_ios url_launcher_linux url_launcher_macos url_launcher_platform_interface url_launcher_web url_launcher_windows] dev dependencies: - flutter_test 0.0.0 [flutter test_api matcher path fake_async clock stack_trace vector_math async boolean_selector characters collection material_color_utilities meta source_span stream_channel string_scanner term_glyph web] transitive dependencies: - _flutterfire_internals 1.3.16 [collection firebase_core firebase_core_platform_interface flutter meta] - args 2.3.1 - async 2.11.0 [collection meta] - boolean_selector 2.1.1 [source_span string_scanner] - characters 1.3.0 - clock 1.1.1 - collection 1.18.0 - connectivity_for_web 0.4.0+1 [connectivity_platform_interface flutter_web_plugins flutter] - connectivity_macos 0.2.1+2 [flutter connectivity_platform_interface] - connectivity_platform_interface 2.0.1 [flutter meta plugin_platform_interface] - crypto 3.0.3 [typed_data] - dbus 0.7.8 [args ffi meta xml] - device_info_plus_platform_interface 7.0.0 [flutter meta plugin_platform_interface] - fake_async 1.3.1 [clock collection] - ffi 2.0.1 - firebase_core_platform_interface 5.0.0 [collection flutter flutter_test meta plugin_platform_interface] - firebase_core_web 2.10.0 [firebase_core_platform_interface flutter flutter_web_plugins js meta] - firebase_messaging_platform_interface 4.5.18 [_flutterfire_internals firebase_core flutter meta plugin_platform_interface] - firebase_messaging_web 3.5.18 [_flutterfire_internals firebase_core firebase_core_web firebase_messaging_platform_interface flutter flutter_web_plugins js meta] - flutter_local_notifications_linux 4.0.0+1 [dbus ffi flutter flutter_local_notifications_platform_interface path xdg_directories] - flutter_local_notifications_platform_interface 7.0.0+1 [flutter plugin_platform_interface] - flutter_web_plugins 0.0.0 [flutter characters collection material_color_utilities meta vector_math web] - freezed_annotation 2.4.1 [collection json_annotation meta] - http_parser 4.0.1 [collection source_span string_scanner typed_data] - in_app_review_platform_interface 2.0.5 [flutter url_launcher plugin_platform_interface platform] - js 0.6.7 [meta] - json_annotation 4.8.1 [meta] - matcher 0.12.16 [async meta stack_trace term_glyph test_api] - material_color_utilities 0.5.0 [collection] - meta 1.10.0 - path 1.8.3 - path_provider_linux 2.1.7 [ffi flutter path path_provider_platform_interface xdg_directories] - path_provider_platform_interface 2.0.4 [flutter platform plugin_platform_interface] - path_provider_windows 2.1.7 [ffi flutter path path_provider_platform_interface win32] - petitparser 5.1.0 [meta] - platform 3.1.0 - plugin_platform_interface 2.1.3 [meta] - process 4.2.4 [file path platform] - shared_preferences_android 2.2.0 [flutter shared_preferences_platform_interface] - shared_preferences_foundation 2.3.0 [flutter shared_preferences_platform_interface] - shared_preferences_linux 2.3.0 [file flutter path path_provider_linux path_provider_platform_interface shared_preferences_platform_interface] - shared_preferences_platform_interface 2.3.0 [flutter plugin_platform_interface] - shared_preferences_web 2.2.0 [flutter flutter_web_plugins shared_preferences_platform_interface] - shared_preferences_windows 2.3.0 [file flutter path path_provider_platform_interface path_provider_windows shared_preferences_platform_interface] - sky_engine 0.0.99 - source_span 1.10.0 [collection path term_glyph] - stack_trace 1.11.1 [path] - stream_channel 2.1.2 [async] - string_scanner 1.2.0 [source_span] - term_glyph 1.2.1 - test_api 0.6.1 [async boolean_selector collection meta source_span stack_trace stream_channel string_scanner term_glyph] - timezone 0.9.1 [path] - typed_data 1.3.1 [collection] - uni_links_platform_interface 1.0.0 [flutter plugin_platform_interface] - uni_links_web 0.1.0 [flutter flutter_web_plugins uni_links_platform_interface] - url_launcher_android 6.0.17 [flutter url_launcher_platform_interface] - url_launcher_ios 6.0.17 [flutter url_launcher_platform_interface] - url_launcher_linux 2.0.3 [flutter] - url_launcher_macos 2.0.3 [flutter] - url_launcher_platform_interface 2.1.0 [flutter plugin_platform_interface] - url_launcher_web 2.0.12 [flutter flutter_web_plugins url_launcher_platform_interface] - url_launcher_windows 2.0.2 [flutter] - vector_math 2.1.4 - web 0.3.0 - win32 5.0.3 [ffi] - win32_registry 1.1.1 [ffi win32] - xdg_directories 0.2.0+1 [meta path process] - xml 6.1.0 [collection meta petitparser] ```

darshankawar commented 8 months ago

Thanks for the detailed report @amandaoneal There was a recent fix made related to notification limit https://github.com/firebase/flutterfire/issues/11771 , https://github.com/firebase/flutterfire/pull/12060 that you can check and see if it helps in your case or not.

The fix is not yet released in new plugin verion.

amandaoneal commented 8 months ago

That seems likely to help, but not fully fix my case - that change seems to just increase the limit from 20 to 100. There are realistic scenarios where my users would want more than 100. Is there a real reason to have that limit in place at all? If so, is there a real reason not to bump it up to a big number like 10,000?

darshankawar commented 8 months ago

Thanks for the update @amandaoneal I think it is essentially same issue as I linked previously. Once new version of the plugin is published, I suggest you to re-verify your case to check if tapping on 21st or older notification but < 100 works properly or not.

Is there a real reason to have that limit in place at all? If so, is there a real reason not to bump it up to a big number like 10,000?

This probably is a question for native. From docs, it says:

For Android there is a limit of 100 messages that can be stored without collapsing. If the limit is reached, all stored messages are discarded.

Also check https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

amandaoneal commented 8 months ago

Ah - I didn't realize the 100 number was a limitation from a lower level of the code. I'll close this out then, as #12060 fixes this as well as it's going to without a change in the underlying native code. Thanks!