来自无服务器MongoDB应用服务后端的Apple推送通知



我一直在为iOS应用程序设置Apple推送通知,使用JSON Web令牌而不是证书。

我可以生成一个JWT,并在应用程序中发出所需的POST请求(使用Swift JWT包(,然后通知就会送达。

我使用的是MongoDB Realm,它具有从iOS应用程序调用的无服务器功能(在带有Node环境的JavaScript中(。一个预定的触发器会更新我的JWT,正如苹果建议的那样,它应该每小时刷新一次。

然而,尽管尝试了几个Node模块来发出POST请求,但始终存在错误(如"BadDeviceToken"或"InvalidProviderToken"(。


我终于用node-amp包让它工作了!然而,我有两个关于在这个无服务器功能上下文中使用它的查询:

  1. 它试图保持与苹果服务器的连接打开,这很好,只是这可能意味着每次调用函数时都会打开一个新的连接。调用Provider.shutdown()似乎不会停止连接。我不认为我可以有一个长时间运行的进程来在无服务器环境中接收未来的请求
  2. 苹果公司建议,刷新JWT的频率不要超过每20分钟一次。node-apn为您管理JWT,但在无服务器上下文中,它会在每次调用函数时生成一个新的令牌吗?每次我在开发模式下测试它(到苹果沙盒端点(时,似乎都会收到通知

如果能澄清这些问题,以及node-apn是否适合用于无服务器功能,我将不胜感激。


更新

Provider.shutdown()不起作用似乎是一个公认的问题。

我可以使用以下变通方法关闭:

Provider.client.endpointManager._endpoints.forEach(endpoint => endpoint.destroy());

我仍然想知道在无服务器功能中使用它是否合理。我担心JWT的每一个请求都会被刷新,苹果可能不喜欢!

我浏览了苹果关于这方面的文档,并考虑了您关于在无服务器上下文中刷新令牌的问题。

根据苹果的文档,你可以想象以下方法来确保你每20分钟刷新一次代币,每小时至少刷新一次:

  1. 生成用于发送单个通知请求的令牌
  2. 发送通知,然后在后台将该令牌保存到MongoDB内部的某个集合(例如apn_tokens((可选地与createdAt时间戳字段一起(
  3. 在下一个发送推送通知的请求中,从服务器获取存储的JWT令牌。
    • 如果令牌的createdAt日期(或JWT本身的iat字段(小于一小时(或在小于一小时的某个阈值内,例如50分钟(,则在发送推送通知请求时重用令牌
    • 否则,请从步骤1重新启动进程

请注意:这将要求您的数据库(或apn_tokens集合(只能从受信任的来源(即仅您的云应用程序/功能(访问,如果它们还没有访问的话。客户端不应以任何方式访问此表。您可以想象为您的无服务器环境设置集合级访问控制。作为一个额外的安全层,你可以想象删除";过期";在步骤1中重新生成后的令牌,使得在任何时候表中都只有一个令牌,以防止潜在的活动令牌在没有使用的情况下分布在数据库中。

我希望这能有所帮助!

最新更新