简体   繁体   English

iOS没有使用apn nodejs接收后台推送通知

[英]iOS not receiving background push notification using apn nodejs

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. 我在智慧结束时,我已经尝试了我可以通过Stack Overflow找到和搜索的每个教程。

  • Device and APN are set to debug/development 设备和APN设置为调试/开发
  • I can successfully register device token 我可以成功注册设备令牌
  • I have an active .p8 key with push notification services 我有一个带有推送通知服务的活动.p8密钥
  • APN says the push message was sent successfully APN表示推送消息已成功发送
  • didReceiveRemoteNotification doesn't fire didReceiveRemoteNotification不会触发
  • Tried with app in background and foreground 尝试在背景和前景中的应用程序
  • using AWS: inbound - port 22, outbound - all ports 使用AWS:入站 - 端口22,出站 - 所有端口

This is the response: 这是回应:

{"sent":[{"device":"cc7ec9a821cf232f9510193ca3ffe7d13dd756351794df3f3e44f9112c037c2a"}],"failed":[]} { “发送”:[{ “设备”: “cc7ec9a821cf232f9510193ca3ffe7d13dd756351794df3f3e44f9112c037c2a”}], “失败”:[]}

Here is my code: 这是我的代码:

AppDelegate.swift 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: 的XCode:

在此输入图像描述 在此输入图像描述

Node.js Node.js的

.p8 key is from Developer Console: Keys > All .p8密钥来自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. 'aps'不属于有效负载字段,而应该位于通知构造函数中。

Node.js: 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. 我不确定是否是这种情况,因为您的服务器正在使用此APN节点模块而我从未使用它,但我使用Firebase并且每次尝试使用content_available : 1 ,它都无效。 What did work was content_available : true . 什么工作是content_available : true

Hope this works for you. 希望这对你有用。

You wrote this on your AppDelegate 你在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. 这意味着您的AppDelegate 不是 notificationCenter的委托。

either change that to 要么改变为

 center.delegate = self 

Or just remove that function to the class that adopts it ie your UYLNotificationDelegate 或者只是将该函数移除到采用它的类,即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. 虽然我不知道如何读取node.js,因此您可能已将错误配置为错误。 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: 来自Apple的示例有效负载应如下所示:

 { "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. 我错误地建议您应该将center.delegate = notificationDelegate更改为center.delegate = self但如果我是绝望的话,我会试一试: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 :/ 可能它不起作用:/

  • Delete the app and then install it again. 删除该应用程序,然后重新安装。 Sometimes the authorizations don't work correct if you just reinstall. 如果您只是重新安装,有时授权无法正常工作。
  • clean derived data, clean build, restart Xcode. 清理派生数据,清理构建,重新启动Xcode。

After your EDIT: 编辑后:

You shouldn't have deleted the didReceive Remote Notification <-- this is for retrieving any push notification that has content-available : 1 . 您不应该删除didReceive 远程通知< - 这是用于检索任何具有content-available : 1推送通知content-available : 1

  • The willPresent is callback for what to do if app is in FOREGROUND. 如果app在FOREGROUND中, willPresent将回调该怎么办。 Only applicable if payload has alert or badge or sound in payload. 仅当有效载荷在有效载荷中具有警报或徽章或声音时才适用
  • The didReceiveNotificationResponse is NOT what you think it is. didReceiveNotificationResponse不是你想象的那样。 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. 您使用此回调处理对通知的响应

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. 如果你在前台有一个应用程序,并且有效负载有: content-available :1也有动作而用户点击了动作,那么你将首先获得第3个回调,然后是第一个回调,然后是第二个回调。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM