I download Example, run the project and find out that didReceiveRemoteNotification callback works always when phone connected to mac (by cable or wireless debugging), in this case it works in foreground, background and on locked screen as well. But if phone does not connected to mac, the didReceiveRemoteNotification callback fires only when app in foreground.
To check this I added simple request to server in didReceiveRemoteNotification, which send current time to database.
Here is my code:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("application:didReceiveRemoteNotification:fetchCompletionHandler: called, with notification:")
let date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy hh:mm:ss"
let result = formatter.string(from: date)
// prepare json data
let json: [String: Any] = ["title": result]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "https://testfirebase-5d1ab.firebaseio.com/testCollection.json")!
var request = URLRequest(url: url)
request.httpMethod = "PUT"
// insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()
print("\(userInfo.jsonString ?? "{}")")
completionHandler(.newData)
}
My notification payload to FCM is:
{
"to": "device_id",
"content_available": true,
"priority": "high",
"data": {
"someParam": true
}
}
In firebase console, I set up my APNs Authentication Key.
In xCode in project capabilities Enabled Push Notification and Background Modes->Remote notification.
For simple testing I create firebase database, you can login by this account
[email protected]
zxc123zxc
didReceiveRemoteNotification according to my example.There is a known issue in iOS 11.0 where iOS is not processing silent notifications often. This is fixed in iOS 11.1 beta 1.
In my own testing on iOS 11.0, I've noticed this issue on my test devices. Are you able to see if this is fixed in 11.1?
If you are receiving the silent notification sometimes, it generally means that your FCM API calls / FCM SDK integration is working fine. If it was broken it would never work.
If this is happening also in iOS 9.3.5, keep in mind that silent notifications are disabled by iOS if:
@rsattar, thank you for reply!
I've tested it on 9.3.5 again and find out that it works when app in foreground and background but only when connected with cable.
When I disconnect cable and move app to the background - nothing happens, the same situation like with iOS 11.0.2.
Also I try to drop app from processes and than start it again and move to background - still not working, only when app in foreground :sob:
I was check this by depends on items listed below:
I try to use PushNotificationIOS on iOS 9.3.5 and 11.0.2 by APNs. So I find out that on 9.3.5 it works in background without connected cable, didReceiveRemoteNotification fires each time well. But it didn't work on 11.0.2, it works like I described above.
@Vetalyo In your app are you registering for the UNNotificationCenterDelegate? If so, then you don't receive didReceiveRemoteNotification, it'll arrive in center:willPresentNotification:completionHandler:.
@rsattar, I can't found this method in your sample project. Could you please explain your answer in more details?
Why it should not work with this method didReceiveRemoteNotification, if it's works well with cable?
Thank you.
He's talking about this UNUserNotificationCenterDelegate method.
In your case, silent notifications may be getting throttled in the background (see the notice under "Configuring a Silent Notification" here).
@morganchen12 , thanks for reply!
No, I'm not using UNNotificationCenterDelegate in my app. I just run messages example form master branch.
In your case, silent notifications may be getting throttled in the background (see the notice under "Configuring a Silent Notification" here).
Can you please help me figured out. How to make it work correctly ? I really need this functionality in my app 馃槶
While testing I send only one notification, but it doesn't work. As I understand notification will be throttled when sending a lot of notification at short time.
Also I tested your example on iOS 10.3.3 - the same result - it works only when iPhone connected to cable. When cable disconnected - didReceiveRemoteNotification callback does not work.
I'm not entirely certain the extent of Apple's silent notification throttling, but their documentation states:
The system tracks the elapsed time, power usage, and data costs for your app鈥檚 background downloads. Apps that use significant amounts of power when processing remote notifications may not always be woken up early to process future notifications.
Your callback code does several relatively expensive things, which could be deferred to reduce the cost of the callback and potentially the amount you're getting throttled.
DateFormatter in the callback. Initializing DateFormatters is expensive--instead you should initialize the DateFormatter once either lazily or upon AppDelegate initialization, then store it in a property and reference that property throughout your file.JSONSerialization and URLSession: Instead of serializing the small amount of JSON and immediately uploading it, try enqueueing these tasks somewhere and processing them when the app is foregrounded.@morganchen12, thank you for reply!
I already delete this from my code and leave only simple post request.
Result the same.
Are you sure that it works on iOS 9-10 without connected cable?
Yes, FCM does not do any of its own client-side throttling. If you remove the post request as well so the method stub is completely empty aside from calling the completion handler, is there any change?
Okay, could you please provide me, how to check that it works if I remove the post request?
Sorry for stupid question, I'm working with React-Native and I'm newbie in Swift.
Thank you for help.
You can just add a log statement. (ObjC NSLog(), Swift print())
How I gonna see NSLog() or print(), when device not connected to Mac?
In case when I'm using debugging by wireless connection instead cable - it works like with connected cable.
But I need to make it work without connected cable or wireless debugging.
You can find the logs retroactively by plugging in the phone. Alternatively you can opt for something simpler, like presenting a UILocalNotification.
Could you please explain how to check the logs retroactively by plugging in the phone?
Because when I connect phone to mac I found only the way to see logs which start right after connection, without retroactively logs.
Thank you, very appreciate your help!
You're right, looks like Xcode's organizer doesn't show previous log statements. Can you try the UILocalNotification route instead? You can modify your app's badge number to make distinguishing easier.
Okay, It's works with UILocalNotification, badge changing always correctly. But in documentation I saw that I can use silent notifications to make request and update data.
I need to get data from phone and save it to server.
Thank you for reply!
You'll still be able to do that--what we were trying to measure by reducing the logic in your application callback was how much the system is throttling your silent notifications. Instead of directly sending the upload requests in the notification handler, you should queue them somewhere and have your app upload them all at once when foregrounded.
I'm going to close this issue as it seems we've appropriately diagnosed your problem, but if you have any other questions feel free to continue commenting.
That's great, but that's have no sense for me. Because I need to get this data from user on receiving the silent notification, that's why I'm sending silent notification.
I can send this data from user without any push/silent notification's at all.
Just make this request on event - app comes to foreground.
So that's not a solution for me.
I need to send it in moment when silent notification comes 馃槶
Thank you for reply!
Hi, I am using the same silence push notifications to schedule local push notifications for a calendar app.
1) The server notifies by a silence push that there is a new event in the calendar.
2) The client must use that silence push to schedule reminders for that event using local push notifications.
But I can only receive this push when I am in foreground. Is possible to receive them when I am in background or the app is killed? In android this feature is working.
Hi, I am using the same silence push notifications to schedule local push notifications for app.
I can only receive this push when I am in foreground and background . is it possible to receive them when app is killed? for ios??
iOS will not send silent notifications if the user manually force-quits your app. Unfortunately this is a platform behavior.
@morganchen12 thanks for quick reply :)
i am totally new in swift so plz help me out
let notification = UILocalNotification()
notification.fireDate = NSDate(timeIntervalSinceNow: 1) as Date
print("hello")
notification.alertTitle = userInfo["title"] as? String
notification.alertBody = userInfo["message"] as? String
notification.alertAction = "Ok" // used in UIAlert button or 'slide to unlock...' slider in place of unlock
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = userInfo // Array of custom parameters
notification.applicationIconBadgeNumber = 1
UIApplication.shared.scheduleLocalNotification(notification)
i m using this local notification so
it is not possible to get notification when app was killed?
If this local notification code is in a silent notification handler, it won't get called when the app has been force-quit by the user.
Most helpful comment
There is a known issue in iOS 11.0 where iOS is not processing silent notifications often. This is fixed in iOS 11.1 beta 1.
In my own testing on iOS 11.0, I've noticed this issue on my test devices. Are you able to see if this is fixed in 11.1?
If you are receiving the silent notification sometimes, it generally means that your FCM API calls / FCM SDK integration is working fine. If it was broken it would never work.
If this is happening also in iOS 9.3.5, keep in mind that silent notifications are disabled by iOS if: