Closed davidbrenner closed 2 years ago
I'm also experiencing this. The best solution to this would be to make swizzling optional. It's frustrating when frameworks implement swizzling and it breaks other dependencies and there is no way to turn it off
We stopped using OneSignal because of this. If someone can confirm that solution works, I might be able to schedule some time into exploring this again, but for now I can't put more time into it.
Moving the steps into this issue as well for easier visibility.
If the application is subclassing FlutterAppDelegate (probably most common) the apps simply need to implement the UNUserNotificationCenter protocol in the AppDelegate.h
file.
@interface AppDelegate : FlutterAppDelegate <UNUserNotificationCenterDelegate>
set itself as the UNUserNotificationCenterDelegate
in application:didFinishLaunchingWithOptions:
if (@available(iOS 10.0, *)) {
[UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;
}
Finally in the protocol method implementations call Super. This calls the FlutterAppDelegate version of these methods.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
[super userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
[super userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
If your Application is not subclassing FlutterAppDelegate as described in the Flutter doc here the app will do something similar but will call the method directly on the _lifeCycleDelegate
instead of Super.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
[_lifeCycleDelegate userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
[_lifeCycleDelegate userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
@emawby AppDelegate in swift ?
@MohammedAlimoor Your AppDelegate file may be in Swift or it maybe in AppDelegate.h and AppDelegate.m in Objective-C
@emawby
This is mine AppDelegate.swift file:
import UIKit
import Flutter
import GoogleMaps
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
super.userNotificationCenter(center, willPresent: notification, withCompletionHandler: completionHandler)
}
override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
super.userNotificationCenter(center, didReceive: response, withCompletionHandler: completionHandler)
}
}
...and it's not passing notifications to dart part.
when app is in the foreground, nothing happens, when it's in the background or terminated, notification arrives but the notification object does not get passed to the dart part.
console log displays this:
'Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.'
any ideas what might have gone wrong?
when oneSignal plugin gets removed from our futter app, everything works fine :)
@jelenalecic It doesn't look like your AppDelegate class specified that it is also a UNUserNotificationCenterDelegate
on line 6
Closing this issue with the workaround posted in the thread.
@jelenalecic you need to cast the current delegate to UNUserNotificationCenterDelegate
as follow:
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
Then you have to swizzle the methods of the UNUserNotificationCenterDelegate
as you need. In my case I wanted to trigger the callback of the FirebaseMessaging, and that only works for me after calling Messaging.messaging().appDidReceiveMessage(userInfo)
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken;
super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
}
override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
Messaging.messaging().appDidReceiveMessage(userInfo)
// Uncomment this line to receive notifications on foreground
// completionHandler([[.alert, .sound]])
super.userNotificationCenter(center, willPresent: notification, withCompletionHandler: completionHandler)
}
override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
Messaging.messaging().appDidReceiveMessage(userInfo)
completionHandler()
super.userNotificationCenter(center, didReceive: response, withCompletionHandler: completionHandler)
}
override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
Messaging.messaging().appDidReceiveMessage(userInfo)
completionHandler(.noData)
super.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
}
Hope my solution work for you.
Hi! Unfortunately none of the solutions provided by @emawby (here) or @tayseer9 (here) worked for me. Same problem as mentioned by @jelenalecic. The notification is received but not passed to dart.
When I try to specify that AppDelegate is also UNUserNotificationCenterDelegate
like @emawby mentioned:
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, UNUserNotificationCenterDelegate {
...
}
Compilation fails due to the error:
Redundant conformance of 'AppDelegate' to protocol 'UNUserNotificationCenterDelegate'
I have tried every single approach I found in both the OneSignal and the Firebase Messaging GitHub repos. None of them worked. As long as OneSignal is specified as dependency in pubspec.yaml, Firebase Messaging won't work.
I will attach my current AppDelegate.swift (inspired by @tayseer9). Am I missing something?
@pictureframing Did you manage to solve it? I have the same problem.
@emawby I have exactly the same problem. If onesignal_flutter is in the pubspec, FirebaseMessaging handlers do not work. Tried everything in this thread. At end, I have the same "Redundant..." problem as @picturefarming
Hi @rserro, no we were not able to solve it. The answer from the customer support team of OneSignal was that it just does not work. No further help from their side. We postponed the project we needed this for but will probably go with another solution then having both of the packages as dependencies.
Ok, thanks @pictureframing !
Same problem for us...One Signal is not providing solutions and this is not a priority...very disappointing
Update, we were able to reproduce this bug and opened a bug report with FlutterFire. Feel free to monitor https://github.com/firebase/flutterfire/issues/8792 for more updates.
Update, I have summited a PR to the FlutterFire SDK to accelerate the process in getting the issue fixed: https://github.com/firebase/flutterfire/pull/8822
https://github.com/firebase/flutterfire/pull/8822 as been merged, this means it will be included in their next release. Closing this issue.
Google has shipped the fix for this in firebase_messaging 11.4.2. The following change log entry relates to this:
Description:
OneSignal Flutter v2.6.2 not working with Firebase Cloud Messaging 8.0.0-dev.14
Environment
Steps to Reproduce Issue:
The message is received, but the FCM handlers are not called when the message is opened. Before installing OneSignal, this was working. Additionally, FCM was working with OneSignal on older builds of this app. As part of tracking down this issue, I created a new project and added anything involving notification-related code step-by-step. Once OneSignal was added and configured, FCM's handling broke.
We use both OneSignal and FCM APIs separately, but FCM is far more important to us than OneSignal, so our solution is going to be to just remove OneSignal. We would still like to use it if there is a solution.
Anything else:
N/A