My device is not receiving background push notifications. I'm at wits end, I've tried every tutorial I can find and searched through Stack Overflow.
This is the response:
{"sent":[{"device":"cc7ec9a821cf232f9510193ca3ffe7d13dd756351794df3f3e44f9112c037c2a"}],"failed":[]}
Here is my code:
AppDelegate.swift
import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10, *) {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
if error == nil {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
var deviceTokenString: String = ""
for i in 0..<deviceToken.count {
deviceTokenString += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
}
UserDefaults.standard.set(deviceTokenString, forKey: "push_token")
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) {
print("Handle push from foreground")
print("\(notification.request.content.userInfo)")
completionHandler([.alert, .badge, .sound])
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("Handle push from background or closed")
// if you set a member variable in didReceiveRemoteNotification, you will know if this is from closed or background
print("\(response.notification.request.content.userInfo)")
completionHandler()
}
}
XCode:
Node.js
.p8 key is from Developer Console: Keys > All
var apn = require('apn');
var apnProvider = new apn.Provider({
token: {
key: "/path/to/AuthKey_1234ABCD.p8",
keyId: "1234ABCD",
teamId: "1234ABCD"
},
production: false
});
var note = new apn.Notification();
note.topic = "com.company.app";
note.payload = {
aps: {
"content-available" : 1
},
custom_field: {}
};
apnProvider.send(note, push_token).then(result => {
console.log('result: ', result);
console.log("sent:", result.sent.length);
console.log("failed:", result.failed.length);
});
I appreciate everyone's input, I figured out the issue.
'aps' does not belong in the payload field, but instead should be in the Notification constructor.
Node.js:
var note = new apn.Notification({
aps: {
"content-available" : 1
}
});
note.payload = {
custom_field_1: {},
custom_field_2: ''
};
I'm not sure if this is the case as your server is using this APN node module and I never used it, but I use Firebase and everytime I tried using content_available : 1
, it didn't work. What did work was content_available : true
.
Hope this works for you.
You wrote this on your AppDelegate
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { print("Silent push notification received: \\(userInfo)") }
But then you also wrote:
center.delegate = notificationDelegate
which means you're AppDelegate isn't the notificationCenter's delegate.
either change that to
center.delegate = self
Or just remove that function to the class that adopts it ie your UYLNotificationDelegate
You seem to have it all right. Though I don't know how to read node.js so you may have configured your payload incorrect. Also sometimes if the server isn't managing multiple device tokens correctly you may not get a silent notification at all or another issue we have with our backend was that they were redirecting the notifications server to their local machine while we're testing the notifications, obviously they weren't coming in!
A sample payload from Apple should look like this:
{ "aps" : { "content-available" : 1 }, "acme1" : "bar", "acme2" : 42 }
Are you sure your generated payload has a similar format?!
I wrongly suggested to that you should change center.delegate = notificationDelegate
to center.delegate = self
but if I was that desperate I'd give that a try :D.
Make sure background App Refresh is enabled (though still without that enabled you should receive in foreground
If this doesn't work, then try sending it with an alert/badge and see if that works. Likely it won't work :/
After your EDIT:
You shouldn't have deleted the didReceive Remote Notification <-- this is for retrieving any push notification that has content-available : 1
.
willPresent
is callback for what to do if app is in FOREGROUND. Only applicable if payload has alert or badge or sound in payload. didReceiveNotificationResponse
is NOT what you think it is. It's for handling managing what action the user chose from the notification eg your notification has two actions (Snooze, delete) to click like below: You handle the Response to the notification using this callback.
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
is used for retrieving the notification upon arrival. So technically speaking if you just have a silent notification you would only get the third callback and not the first two.
If you had an app in the foreground and the payload had: content-available :1
which also had actions and the user tapped on the action then you would first get the the 3rd callback, then the 1st callback and then the 2nd callback.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.