ios 10 Firebase Push Notification delegate method not called in background mode - ios

I have been struggling with this problem for days and I have looked at every post about this and nothing works.
I am using FCM (Firebase Cloud Messaging). FCM talks directly to the app when in foreground, but it will use APNS when the app is in background.
I am trying to call a method everytime the app got notification by calling the method in the push notification's delegate function
I have these 2 delegate functions:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void)
and
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void)
which does not get called in background, according to apple documentation.
I also have this function which I believe should get called in the background but it does not.
func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
I have all of these functions in ViewController
In background mode, I get banner notifications, but none of the delegate is called. Is there any way to make any of them work in the background, if not what should I do?
In addition I also get this error : <FIRMessaging/WARNING> FIRMessaging receiving notification in invalid state 2 in the log everytime I send a payload while the app is in the background.
Here is the payload that I send using postmate:
{
"priority":"high",
"notification":{
"sound": "default",
"badge": "1",
"title":"mytitle",
"body":"mybody",
"message":"Hello"
},
"content_available":true,
"to" : "/topics/myTopic"
}
I already turned on push notification in capabilities and checked push notification in background modes under capabilities.
I use Xcode 8 and have been testing on iphone 6 iOS 10.0.2

There can only be 1 delegate for a protocol.
In this case, I made APPDelegate and ViewController conform to UIApplicationDelegate. And only delegate functions in APPDelegate got called. That's why the one in ViewController is not called.
The solution would be just put didReceiveRemoteNotification in the AppDelegate.

Related

Unable to trigger didReceive notification delegate when you bring the app from background to foreground

I have implemented push notification for ios10. Tapping on the notification alert would trigger "didReceive" delegate, were i save the notification in coredata or silent notification if i m in foreground. The problem is if i receive a stack of notification in background and When i bring my app to foreground from background, Is there a possibility to call "didReceive" delegate or any other push notification delegate were i could sync my items to coredata.
Note
I don't want to sync(didReceive or any delegate) the items in background using silent notification nor tapping on the alert. It should sync automatically the stack of push notification when i bring the app to foreground
func handleInboxNotification(didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
if let inboxValue = userInfo["inbox"] as? String, let value = inboxValue.boolValue(), value {
let mappedMessage = MessageCenterSDK.shared.constructReorderedDictionary(userInfo: userInfo)
MessageCenterDataManager.shared.synchronize(messages: mappedMessage)
messageCenterDelegate?.didFindNewMessages(hasNewMessages: true)
}
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
/// Handle outbound remote
handleInboxNotification(didReceiveRemoteNotification: response.notification.request.content.userInfo)
completionHandler()
}
I was facing the same issue, but my target was for iOS 13 & I'm using BGTaskScheduler to fetch data from the server in the background as well in terminated state.
I too want to trigger the notification when the app is in background. But not tapped but that seems to be not possible so we have changed our implementation by enabling background mode and it worked for me.
Hope it also helps.
For more reference on BGTaskScheduler, https://developer.apple.com/documentation/backgroundtasks/bgtaskscheduler
you need to use willpresent delegate in appDelegate
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
// Change this to your preferred presentation option
completionHandler([])
}
This delegate is called when a notification comes in foreground

UNUserNotificationCenterDelegate didReceive is not getting triggered in iOS with Flutter App

I have setup push notifications using APNS for iOS (Using Swift) in the flutter App. didReceiveRemoteNotification is getting triggered when the app receives a push notification from AWS Pinpoint. But none of the other methods are getting triggered when the user taps the notification. Once I handle the user action on the push notification, I can call a scheme using openUrl to specific route on the app.
I have tried by disabling/enabling background modes in the capabilities in the Xcode. Also verified that push notifications are turned on in the capabilities. Pinpoint uses APNS to send the notification to iOS and Firebase to send the notification to Android which is working fine.
Also tried with iOS target version as 10.0, 11.0 and 12.0
UNUserNotificationCenter.current().delegate = self
is declared in didFinishLaunchingWithOptions and imported UserNotifications
When I tap the push notification, this is getting printed in the console:
Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.
Payload from pinpoint:
[AnyHashable("aps"): {
alert = {
body = "BODY";
title = "TITLE";
};
badge = 0;
"content-available" = 1;
"mutable-content" = 0;
sound = default;
}]
Code,
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// Print full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print full message.
print(userInfo)
completionHandler()
}
}
didReceive is expected to get triggered when the user taps on the push notification which is not happening in my case.
Can anyone help me on how to trigger when the user taps the push notification?
I was facing a similar problem. iOS swift delegate methods were not triggered. It appears that the methods must have been declared public.
Just replace
func userNotificationCenter
with
public func userNotificationCenter
Maybe it will helps someone...
Have you set center's delegate property?
center.delegate = self
where self is AppDelegate.

How to handle push notification payload without tapping it when the app is in not running or background state

I have to locally store Title and Body of all the notifications coming in my iOS app and display those in a notifications screen. I'm able to store all the notification tapped by using these-
This gets called when the app is in not running state or killed when the push notification is tapped-
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {...}
This gets called when app is running in foreground or background and push notification is tapped-
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {...}
My question is how to store notifications without tapping on notifications.
I want to store the notifications even if the notification is dimissed/cleared by user.
I know this method is called when app is active and in the foreground and push notification comes-
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {..}
How to handle push notification data without tapping on it when the app is in background or not running state?
1- If the app isn't running then no way to wake up the app only with ( VOIP )
2- if in background then add this key to the sended payload
"content_available": true
And enable RemoteNotifications from app capabilities

Swift: Getting Data from Remote notification

I have a messaging app, which gets data from server through push notification.
In the following image, you can see the process and also check where it gets faulted:
I have researched a lot about this problem but not getting a universal solution.
One solution I get is to use silent notification , discussed Here , to get data before it is shown and save it. But I didn't find how to show notification from app delegate once I received silent notification.
Kindly correct me if I am conceptually wrong somewhere.
Update:
One of problem is that the application:didReceiveRemoteNotification:fetchCompletionHandler: is only called when
app is in foreground
user clicks the notification
But when user doesn't click the notification, application:didReceiveRemoteNotification:fetchCompletionHandler: is not called, and I can't find a way to save the data, that is present in notification.
Your question is "To get data from Remote notification while the App is in foreground" if im correct, You can use these two methods to get data from Remote notifications for background and foreground app modes.
// Notification will present call back
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound, .badge])
// Handle your data here
print("Notification data: \(notification.request.content.userInfo)")
}
#available(iOS 10.0, *)
// Notification interaction response call back
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
// Handle your data here
print("Notification data: \(response.notification.request.content.userInfo)")
}
There are two cases:
Background
Closed State
If the app is in Background State, you have to enable Background Fetch, then this method will be called when the app is in Background application:didReceiveRemoteNotification:fetchCompletionHandler:
When the app is closed or killed by the user the above method not gonna work, for that you can use the VoIP technique.
didReceiveIncomingPushWithPayload method will be called whenever Remote Notification arrives
You can find more details about VoIP here

What's UserNotification framework's equivalent of didReceive notification: UILocalNotification?

I already knew about this code which can be used before iOS 10:
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
}
However, it's depreciated so I just want to ask is there any method that is equivalent to the UserNotifications framework or I just have to get by with this warning?
Note that I want the app to do something when app is in the background or is terminated.
The deprecated method was notifying delegate when the app received notification while in foreground. Now UNUserNotificationCenterDelegate does the same thing:
func userNotificationCenter(
UNUserNotificationCenter,
willPresent: UNNotification,
withCompletionHandler: #escaping (UNNotificationPresentationOptions) -> Void
)
Called when a notification is delivered to a foreground app.
Documentation.

Resources