【问题标题】:iOS not receiving background push notification using apn nodejsiOS没有使用apn nodejs接收后台推送通知
【发布时间】:2017-07-14 20:13:02
【问题描述】:

我的设备没有收到后台推送通知。我束手无策,我已经尝试了所有可以找到并通过 Stack Overflow 搜索的教程。

  • 设备和 APN 设置为调试/开发
  • 我可以成功注册设备令牌
  • 我有一个带有推送通知服务的活动 .p8 密钥
  • APN 表示推送消息发送成功
  • didReceiveRemoteNotification 没有触发
  • 尝试在后台和前台使用应用程序
  • 使用 AWS:入站 - 端口 22,出站 - 所有端口

这是回复:

{"sent":[{"device":"cc7ec9a821cf232f9510193ca3ffe7d13dd756351794df3f3e44f9112c037c2a"}],"失败":[]}

这是我的代码:

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()
    }
}

X代码:

Node.js

.p8 密钥来自开发者控制台: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);
});

【问题讨论】:

  • 我一直使用cert.pemkey.pem 发送iOS 推送消息。我不知道那个例子是否会有所帮助。我可以发布它,但只是想确认您的情况是否可行
  • @KukicVladimir 你用什么 node.js 库来发送推送通知?
  • 我正在使用apn,和你一样
  • 你的 node-apn 是最新的吗?服务器名称最近更改了。你能检查通知被发送到哪些服务器名称吗?

标签: ios node.js swift apple-push-notifications


【解决方案1】:

感谢大家的意见,我解决了这个问题。

'aps' 不属于 payload 字段,而应该在 Notification 构造函数中。

Node.js:

var note = new apn.Notification({
    aps: {
        "content-available" : 1
    }
});

note.payload = {
    custom_field_1: {},
    custom_field_2: ''
};

【讨论】:

    【解决方案2】:

    我不确定是否是这种情况,因为您的服务器正在使用此 APN 节点模块并且我从未使用过它,但我使用 Firebase 并且每次尝试使用 content_available : 1 时,它都不起作用。起作用的是content_available : true

    希望这对你有用。

    【讨论】:

      【解决方案3】:

      这是你在 AppDelegate 上写的

      func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
              print("Silent push notification received: \(userInfo)")    
          }
      

      但是你也写了:

      center.delegate = notificationDelegate
      

      这意味着你是 AppDelegate不是通知中心的代表。

      要么改成

      center.delegate = self
      

      或者只是将该函数删除到采用它的类中,即你的UYLNotificationDelegate

      你似乎一切都好。虽然我不知道如何阅读 node.js,但您可能配置的有效负载不正确。此外,有时如果服务器没有正确管理多个设备令牌,您可能根本不会收到静默通知,或者我们后端遇到的另一个问题是他们在我们测试通知时将通知服务器重定向到他们的本地机器,显然他们没有进来!

      来自Apple 的示例负载应如下所示:

      {
          "aps" : {
              "content-available" : 1
          },
          "acme1" : "bar",
          "acme2" : 42
      }
      

      您确定您生成的有效载荷具有相似的格式吗?!

      • 我错误地建议您将center.delegate = notificationDelegate 更改为center.delegate = self,但如果我如此绝望,我会尝试一下:D。

      • 确保background App Refresh 已启用(尽管仍未启用,您应该在前台接收

      • 如果这不起作用,请尝试使用警报/徽章发送它并查看 如果那行得通。可能它不会工作:/

      • 删除应用程序,然后 重新安装。有时授权不能正常工作,如果 你只需重新安装。
      • 清理派生数据,清理构建,重新启动 Xcode。

      编辑后:

      您不应该删除 didReceiveRemote通知 content-available : 1 的推送通知。

      • willPresent 是应用程序在前台时要做什么的回调。仅适用于有效负载中包含警报、徽章或声音的情况。
      • didReceiveNotificationResponse 不是您想的那样。它用于处理管理用户从通知中选择的操作,例如您的通知有两个操作(贪睡、删除)可供点击,如下所示:

      您使用此回调处理通知的响应

      所以从技术上讲,如果您只有一个静默通知,您只会收到第三个回调,而不是前两个。

      如果您在前台有一个应用程序并且有效负载有:content-available :1,它也有操作并且用户点击了操作,那么您将首先获得第三个回调,然后是第一个回调,然后是第二个回调。

      【讨论】:

      • 非常感谢您的回复,我已经清理了我的 AppDelegate,以便更容易看到发生了什么
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-23
      • 1970-01-01
      • 1970-01-01
      • 2013-01-14
      • 1970-01-01
      • 2016-11-21
      • 2018-06-21
      相关资源
      最近更新 更多