0

在服务器端,发送苹果推送通知的nodejs平台使用的是node-apn

这是一个带有徽章的示例 - 这是推送的次数。

 const apn = require("apn");

let tokens = ["<insert token here>", "<insert token here>"];

let service = new apn.Provider({ 
  cert: "certificates/cert.pem",
  key: "certificates/key.pem",
});

let note = new apn.Notification({
  alert:  "Breaking News: I just sent my first Push Notification",
  badge: countSendedPushes()
});

note.topic = "<bundle identifier>";

 service.send(note, tokens).then( result => {
   console.log("sent:", result.sent.length);
   console.log("failed:", result.failed.length);
   console.log(result.failed);
 });

事实上,每次我发送推送时,我的数据库徽章都会增加+ 1

当在设备上读取推送时,我减一徽章- 1

每次发送新推送时,我总是发送当前数量的徽章但是如果设备离线它无法推送,但数据库中的数量已经增加。

我怎样才能更正计数徽章

4

1 回答 1

0

如果它成为一个问题,那么也许您不应该乐观地更新数据库?看起来你的推送代码返回了一个 Promise 所以那里有一个自然的流程,例如

service.send(...)
   .then(result => {
       // update badge count in DB
   });

或者,如果您需要乐观地更新,那么如果推送碰巧失败,您可以减少计数

service.send(...)
   .then(result => {
      if (result.failed.length) {
         // decrement badge count in DB
      }
   });

我唯一要说的是,您确定当推送通知失败时,APNS 不会尝试代表您重新发送吗?IIRC APNS 将在最终失败之前继续尝试在 X 周期内提供推送 - 值得确保失败是真正的失败,因为它以后不会重试。


根据评论中的讨论,我认为问题实际上更多是关于不确定设备是否已收到推送通知,而不是知道服务器是否已成功发送它 - 但是,这确实回到了我原来的观点也许你在这里乐观了。

推送通知采用“即发即弃”类型的架构,APNS 没有保证您的消息将被传递到设备,并且没有关于它是否存在的反馈。最终,知道设备收到消息的唯一可靠方法是设备本身告诉您。

这样做的一种方法是向您的推送通知添加一些额外的数据,例如 UUID,服务器可以生成这些数据来表示消息握手的开始。在您的移动应用程序中,收到推送通知后,它可以通过关联 ID 告诉服务器它收到消息来完成握手。自然地,你会从拥有一个单一的“计数”字段的概念转向一个完全成熟的表,例如

MessageID | DeviceToken | SentOn | ReceivedOn

这样的事情不仅可以为您提供所需的计数,还可以为您提供审计跟踪,我认为这对于确定发送与接收、有问题的设备等统计数据非常有用。

于 2017-08-21T12:13:41.867 回答