MaikuB / flutter_local_notifications

A Flutter plugin for displaying local notifications on Android, iOS, macOS and Linux
2.44k stars 1.39k forks source link

firebase_messaging not working if include flutter_local_notifications package on iOS #111

Closed anderscheow closed 4 years ago

anderscheow commented 5 years ago

Method on Firebase Cloud Messaging, onMessage and onResume do not get trigger when I include flutter_local_notifications package.

ghost commented 4 years ago

What if with each version release, we create a branch with name like v0.8.4-+3-firebase-messaging-fix. This way each version release can have its own branch and whenever there is a new release, create a new branch from that release...

This way, it all stays in the same repository...

Just a thought....

MaikuB commented 4 years ago

@sulaysumaria will admit I hadn't thought of that though it's one of those approaches that would add a bit of overhead for me and there's an issue of communicating new branches going to. I suspect that we'll get a new stable release that will coincide with Flutter Interact that would likely include the related engine changes to facilitate being able to use both plugins. This involves developers needing to modify the AppDelegate file of their app as the approach is that plugins shouldn't registering to be a notification delegate (this will be a breaking change). I've made some changes in the 0.9.0 branch in preparation for this already

ghost commented 4 years ago

I agree its a bit overhead, but it is easier compared to each developer maintaining his own branch (that is what happening as no one came forward to maintain a single fork)...

If there is a release coming soon, then there is no need but if there is time before next release (a month or two), then I would suggest to create a separate branch... It is a bit overhead for you but jt is worth as it will allow developers to integrate the package without any hassle.

ishakdas commented 4 years ago

Is the error resolved?

niypoo commented 4 years ago

any new

timeuser commented 4 years ago

Will this be able to be resolved with the latest flutter release?

MaikuB commented 4 years ago

No it won't. I had posted a link to the issue (https://github.com/FirebaseExtended/flutterfire/issues/1455) the main Flutter repository around this in an earlier post

adrianvintu commented 4 years ago

No it won't. I had posted a link to the issue (FirebaseExtended/flutterfire#1455) the main Flutter repository around this in an earlier post

Is it (easily) fixable for them?

MaikuB commented 4 years ago

I don't know anything more beyond what's said in their post that says it should be possible

MaikuB commented 4 years ago

I've done a new release that requires latest stable Flutter SDK release as a minimum. This will enable better support for firebase_messaging but there are still issues. I believe notifications should show without forking now though. If anyone help test to confirm that would be much appreciated. It worked in my brief testing

cielo commented 4 years ago

@MaikuB

First of all, thanks for a great plugin. I tested '0.9.0' version with Firebase Messaging '5.1.4' in Flutter SDK 1.12.13+hotfix.5.

In android, everything works as expected. Both FCM messages from remote server, and your plugin (I call it - FLN)'s scheduled messages show up.

In iOS, when app is minimized (background), the app correctly handles FCM messages, but not FLN's scheduled messages. However, when the app is active (foreground), the app does not handle FCM messages at all, and it also does not handle FLN's scheduled messages. I tested iOS behavior in iPhone 5c running in 10.3.3, and iPhone X running in 13.3.

In AppDelegate.swift file, I made the following changes.

// For scheduled notifications (flutter_local_notifications)
if #available(iOS 10.0, *) {
  UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
MaikuB commented 4 years ago

Thanks for reporting back. I know there are still issues and have mentioned in the readme and earlier. Nothing I can really do on my end at the moment

shadyshrif commented 4 years ago

@MaikuB I would like to thank you for your great work in this issue which is a blocker for many developers to use flutter.

I hope that It could get solved soon.

Noninus commented 4 years ago

Waiting foreground notifications works in these versions:

flutter_local_notifications: ^0.9.1 firebase_messaging: ^6.0.9

MaikuB commented 4 years ago

For those that are willing test out my fork of the firebase_messaging plugin to see if it solves the issue, you can do the following

  firebase_messaging:
    git:
      url: https://github.com/MaikuB/flutterfire.git
      path: packages/firebase_messaging
    <key>FirebaseAppDelegateProxyEnabled</key>
    <false/>

If this works for you, then be great if you could reply back here. This solves the issue from own testing and and I opened a pull request for the Firebase team to review as well

Edit: I also made changes in version 1.0.0 of the plugin so that tapping on push notification from Firebase shouldn't trigger the onSelectNotification callback in this plugin

vagners2 commented 4 years ago

Worked perfectly

MaikuB commented 4 years ago

Glad to hear it! Hopefully it will get reviewed soon.

shadyshrif commented 4 years ago

I'm working on testing it, will give you my feedback within 4 days

timeuser commented 4 years ago

Your fork is working for me. Getting onResume and onMessage execute as they should.

karmazinkd commented 4 years ago

Maybe it's a bit offtopic, but how do you guys get BuildContext inside onMessage:{}, onResume:{}, onLaunch:{} callbacks?

As far I understand we initialize FirebaseMessaging() and add the callbacks as early as we can, in my case I do it in the main() even before I call runApp(MyApp());

So when I tap on my FCM notification and my app starts I get this method called: onLaunch: (Map<String, dynamic> message) async { Navigator.of(context).pushNamed(Router.NOTE); }

I want to open a specific note based on it's id contained in the message, but how (where) do I get BuildContext for that?

karmazinkd commented 4 years ago

Flutter, tested on Android 8.1: firebase_messaging: ^6.0.9 flutter_local_notifications: ^1.1.5+1

in _firebaseMessaging.configure(...) I've implemented all 4 callbacks:

onMessage: { showNotification();} - is called only (as I can see in logs) when the app is ON the foreground when notification arrived. onResume: - is called only when the app is running in the background (was hidden with Home button) onLaunch: - is called only if the app was closed onBackgroundMessage: - has never been called so far.

FlutterLocalNotificationsPlugin().getNotificationAppLaunchDetails().didNotificationLaunchApp - always false, seems that it doesn't work.

Also, I've noticed that even though I've set correct properties for the large icon:

var androidPlatformChannelSpecifics = AndroidNotificationDetails(
        NOTIF_ALL_CHANNEL_ID, NOTIF_ALL_CHANNEL_NAME, 'channel description',
        importance: Importance.Max,
        priority: Priority.High,
        style: AndroidNotificationStyle.BigText,
        largeIcon: Const.APP_NOTIFICATION_LARGE_ICON,
        largeIconBitmapSource: BitmapSource.Drawable);

the notification comes without the big icon (when the app is closed or in the background) but the icon is present if the app was on the foregrund when notification arrives. Do you know what may be the reason?

Levi-Lesches commented 4 years ago

As far I understand we initialize FirebaseMessaging and add the callbacks as early as we can, in my case I do it in the main even before I call runApp(MyApp());

I suppose this doesn't have to be the case. Maybe you could have the initialization code run in initState of MyApp

MaikuB commented 4 years ago

FlutterLocalNotificationsPlugin().getNotificationAppLaunchDetails().didNotificationLaunchApp - always false, seems that it doesn't work.

This is only for local notifications created by this plugin

the notification comes without the big icon (when the app is closed or in the background) but the icon is present if the app was on the foregrund when notification arrives. Do you know what may be the reason?

As you've uncovered in your own testing, firebase notifications appear in the background on their own without invoking any of the callbacks. Take a look at the readme for the firebase_messaging as it describes the various scenarios and callbacks that are invoked. If you have more firebase_messaging related questions, I'd suggest you ask on that GitHub repository or look at one of one of places mentioned at https://flutter.dev/community

locskot commented 4 years ago

Flutter, tested on Android 8.1: firebase_messaging: ^6.0.9 flutter_local_notifications: ^1.1.5+1

in _firebaseMessaging.configure(...) I've implemented all 4 callbacks:

onMessage: { showNotification();} - is called only (as I can see in logs) when the app is ON the foreground when notification arrived. onResume: - is called only when the app is running in the background (was hidden with Home button) onLaunch: - is called only if the app was closed onBackgroundMessage: - has never been called so far.

FlutterLocalNotificationsPlugin().getNotificationAppLaunchDetails().didNotificationLaunchApp - always false, seems that it doesn't work.

Also, I've noticed that even though I've set correct properties for the large icon:

var androidPlatformChannelSpecifics = AndroidNotificationDetails(
        NOTIF_ALL_CHANNEL_ID, NOTIF_ALL_CHANNEL_NAME, 'channel description',
        importance: Importance.Max,
        priority: Priority.High,
        style: AndroidNotificationStyle.BigText,
        largeIcon: Const.APP_NOTIFICATION_LARGE_ICON,
        largeIconBitmapSource: BitmapSource.Drawable);

the notification comes without the big icon (when the app is closed or in the background) but the icon is present if the app was on the foregrund when notification arrives. Do you know what may be the reason?

Maybe it's a bit offtopic, but how do you guys get BuildContext inside onMessage:{}, onResume:{}, onLaunch:{} callbacks?

As far I understand we initialize FirebaseMessaging() and add the callbacks as early as we can, in my case I do it in the main() even before I call runApp(MyApp());

So when I tap on my FCM notification and my app starts I get this method called: onLaunch: (Map<String, dynamic> message) async { Navigator.of(context).pushNamed(Router.NOTE); }

I want to open a specific note based on it's id contained in the message, but how (where) do I get BuildContext for that?

In main.dart: final GlobalKey navigatorKey = new GlobalKey();

in callback: can use functions like navigateToBlack()

Future navigateToBlack(String payload) async { await navigatorKey.currentState.pushReplacement( platformPageRoute( context: navigatorKey.currentState.context, builder: (context) { return BlackView(payload); }, ), ); }

LOG-TAG commented 4 years ago

@MaikuB

what I'm missing only foreground FCM via dashboard working in ios, everything got passed in android! (before adding flutter_local_notifications: ^1.1.6 this all ios scenarios worked fine!)

 firebase_messaging:
    git:
     url: https://github.com/MaikuB/flutterfire.git
     path: packages/firebase_messaging
  flutter_local_notifications: ^1.1.6

MY SWIFT CODE:

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
  ) -> Bool {
    if #available(iOS 10.0, *) {
         UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
       }
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

}

also FirebaseAppDelegateProxyEnabled is configured

Problem: in ios 13 all background and app killed state system tray notification are not received (not able click and onResume, onLaunch since system tray notification not available) when the app becomes foreground the moment I received notification on Onmessage!

payload for ios in FCM console:

contentAvailable true priority high anything else I'm missing for ios config or payload ?

MaikuB commented 4 years ago

@LOG-TAG sorry but I'm having trouble following what your issue is here

LOG-TAG commented 4 years ago

@MaikuB updated

MaikuB commented 4 years ago

If I understood you correctly, you're saying you're not get notifications from firebase when the app is killed. If so then I think there is something else going. I have a sample at https://github.com/MaikuB/flutter_firebase_local_notifications_examples/tree/master/java_objc that uses Objective-C and works fine when I use the console to send a test notification. I don't think would be a problem specific to Swift. I've heard from others that my fork has worked fine for them without any issues as well. You might want to check that and compare with what you've got to see if you misconfigured something

Are you able to add code to your app so that the message object passed from the onMessage call is printed and paste it here as well?

ishakdas commented 4 years ago

Hi @MaikuB the application gives an error in this part. There is no problem when sending data notification.

onBackgroundMessage:myBackgroundMessageHandler,
.
.
.
Future<void> myBackgroundMessageHandler(Map<String, dynamic> message) {
  if (message.containsKey('data')) {
    NotificationHandler.showNotification(message);
  }

  if (message.containsKey('notification')) {}

  return Future<void>.value();
}
LOG-TAG commented 4 years ago

@MaikuB thanks for responding, there are huge confusions when it comes to ios 13(https://github.com/FirebaseExtended/flutterfire/issues/1041) some users are mentioned this also FirebaseAppDelegateProxyEnabled from bool NO to string NO, payload etc update you once resolve it.

MaikuB commented 4 years ago

The official documentation here states that it should be a bool. Given only one user has mentioned using a string and the native Firebase iOS SDK has been available for a while, unless the official documentation has been incorrect for the entire time, it's possible that the other developer made a mistake

MaikuB commented 4 years ago

@ishakdas as covered in #430 and #461, this is best asked on the repository for the firebase_messaging plugin as it relates to running code that uses other plugins with the firebase_messaging.

Edit: also this issue is specific to iOS. That background message handler supposedly only works on Android

LOG-TAG commented 4 years ago

@Maiku do you have any custom modified version of firebase_messaging that supports ios Rich notifications with Notification extension (https://github.com/FirebaseExtended/flutterfire/issues/357)? or any helpful tips to enable that?

MaikuB commented 4 years ago

@LOG-TAG no to both questions but if it's feature you're after, you could look into contributing to firebase_messaging plugin add support for it

ishakdas commented 4 years ago

# 430 ve # 461'de kapsanan @ishakdas , bu, en iyi firebase_messagingeklenti için depoda diğer eklentileri kullanan kodla ilgili olduğu için sorulur firebase_messaging.

Düzenleme: ayrıca bu sorun iOS'a özgüdür. Söz konusu arka plan mesaj işleyicisi sadece Android'de çalışıyor

Isn't this problem related to flutter_local_notifications?

MaikuB commented 4 years ago

@ishakdas no

JonathanJude commented 4 years ago

@MaikuB

what I'm missing only foreground FCM via dashboard working in ios, everything got passed in android! (before adding flutter_local_notifications: ^1.1.6 this all ios scenarios worked fine!)

 firebase_messaging:
    git:
     url: https://github.com/MaikuB/flutterfire.git
     path: packages/firebase_messaging
  flutter_local_notifications: ^1.1.6

MY SWIFT CODE:

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
  ) -> Bool {
    if #available(iOS 10.0, *) {
         UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
       }
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

}

also FirebaseAppDelegateProxyEnabled is configured

Problem: in ios 13 all background and app killed state system tray notification are not received (not able click and onResume, onLaunch since system tray notification not available) when the app becomes foreground the moment I received notification on Onmessage!

payload for ios in FCM console:

contentAvailable true priority high anything else I'm missing for ios config or payload ?

I'm having this same exact issue. Only onMessage works when app is on Foreground. Can't receive notifications when in background.

MaikuB commented 4 years ago

@JonathanJude

hansiiification commented 4 years ago

I'm experiencing the same issue, that notifications only work when the app is in foreground ('onMessage' gets called correctly). When the app is in background no notification is received but onMessage called when reopening the app.

My AppDelegate.m looks like this:

#include "AppDelegate.h" #include "GeneratedPluginRegistrant.h" #import "GoogleMaps/GoogleMaps.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GMSSer"]; [GeneratedPluginRegistrant registerWithRegistry:self]; [UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self; return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end

Help would be appreciated a lot. Anything that I'm obviously doing wrong?

Update: My payload looks like this: const payload = { notification: { title: 'Any title', body:'Any body', }, data: { click_action: 'FLUTTER_NOTIFICATION_CLICK', } }

MaikuB commented 4 years ago

Have you tried a real device as push notifications should be tested on a real device not a simulator. You can see the official FCM docs here that mentions having a physical device as well

hansiiification commented 4 years ago

@MaikuB yes tested on a real device, too but same behavior 😌 trying to find a solution for quite some time now but no luck. I'm afraid there is this one stupid thing I'm doing wrong

MaikuB commented 4 years ago

What version of Flutter are you running and can you create a minimal sample app to reproduce the problem? Alternatively you can try the one I've created at https://github.com/MaikuB/flutter_firebase_local_notifications_examples/tree/master/java_objc that was working for me

MaikuB commented 4 years ago

@hansiiification btw you posted an API key up so I suggest you edit your post, delete your key and regenerate a new one...

hansiiification commented 4 years ago

Hey Michael,

Thanks for the hint with the API key. I edited it and removed it from my cloud console.

I'll try to get your example running later today and get back to you afterwards. Thanks a lot for your help - it is still frustrating though 😉

Best regards, Hans

Von meinem iPhone gesendet

Am 09.03.2020 um 08:45 schrieb Michael Bui notifications@github.com:

 @hansiiification btw you posted an API key up so I suggest you edit your post, delete your key and regenerate a new one...

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

MaikuB commented 4 years ago

No worries. Out of interest does it work when the only plugin you use is firebase_messaging?

hansiiification commented 4 years ago

At least it was working some time ago, but that's exactly what I wanted to test later today to narrow down the issue. The message I'm sending in fact is a correct notification message, right?

Von meinem iPhone gesendet

Am 09.03.2020 um 10:00 schrieb Michael Bui notifications@github.com:

 No worries. Out of interest does it work when the only plugin you use is firebase_messaging?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

pawlowskim commented 4 years ago

I have opposite problem. Notifications are not triggered when app is in foreground. "Native" notification is shown when app is killed or in background. When app is killed firebase messaging onLaunch was called as it should. When firebase messaging onResume is triggered by clicking notification when it's in background I got this in XCode logs:

Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.

firebase messaging onMessage is never called. I'm 100% sure that notifications are send (background and killed is working, also when in foreground I have badge counter bump that is visible right after app is minimised and before it's cleared)

pubspec:

  firebase_messaging:
      git:
          url: https://github.com/MaikuB/flutterfire.git
          path: packages/firebase_messaging
  flutter_local_notifications: 1.2.0+4
  initNotifications() async {
    fm.configure(
        onMessage: (Map<String, dynamic> message) {
          return _onAppForegroundMessage(message);
        },
        onLaunch: (Map<String, dynamic> message) {
          return _onLaunch(message);
        },
        onResume: (Map<String, dynamic> message) {
          return _onResume(message);
        },
        onBackgroundMessage: Platform.isIOS ? null : backgroundMessageHandler);
  }
  initLocalNotifications() {
    if (flutterLocalNotificationsPlugin != null) return;
    flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
    flutterLocalNotificationsPlugin.initialize(
        InitializationSettings(AndroidInitializationSettings("ic_launcher"),
            IOSInitializationSettings()),
        onSelectNotification: _onAgletLocationNotification);
  }
        const pushPayload = {
            notification: {
                title: "title",
                body: `body`
            },
            data: {
                click_action: "FLUTTER_NOTIFICATION_CLICK",
                id: "1",
                type: "xxx"
            },
            android: {
                notification: {
                    sound: "default"
                }
            },
            apns: {
                payload: {
                    aps: {
                        sound: "default"
                    }
                }
            }
        };
import UIKit
import Flutter
import GoogleMaps
import Firebase

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure()
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    }
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
MaikuB commented 4 years ago

@hansiiification I believe so. Note though for my testing, I used the firebase console to send a test message

@pawlowskim did make the modifications to your app's Info.plist file mentioned above?

pawlowskim commented 4 years ago

@MaikuB Yes, I did.

MaikuB commented 4 years ago

@pawlowskim could you paste the output from running flutter doctor -v?