推送通知故障排除和常见问题解答

编辑

关于 Expo 推送通知服务的常见问题集。


在设置 expo-notifications 库和 Expo 推送通知服务时的常见问题和常见问题解答的集合。

Expo 推送通知服务常见问题解答

推送通知服务的费用

通过 Expo 推送通知服务发送通知没有相关费用。

发送通知的限制

每个项目每秒最多可以发送 600 条通知。如果超过此速率,将失败后续请求,直到速率再次低于每秒 600 条。

为了获得最佳结果,我们建议您在服务器上添加速率限制(这在 expo-server-sdk-node 中自动处理)和重试逻辑。

使用 Expo 推送通知服务不是强制的

您可以为 Expo 项目使用任何推送通知服务。 getDevicePushTokenAsync 方法来自 expo-notifications 允许您获取本地设备的推送令牌,您可以将其与其他服务一起使用,甚至可以 通过 FCM 和 APNs 直接发送通知

与通知服务的连接是加密的

Expo 与 Apple 和 Google 的连接是加密的并使用 HTTPS。

通知的内容不被存储

Expo 不会存储推送通知的内容,时间不超过将其传送到 Google 和 Apple 操作的推送通知服务所需的时间。通知仅存储在内存中和消息队列中,而不在数据库中。

通知内容可能会被 Expo 员工看到

如果 Expo 团队正在积极调试推送通知服务,我们可能会看到通知内容(例如,在断点处),但 Expo 不能看到推送通知内容。

投递保障

Expo 尽最大努力将通知投递到 Google 和 Apple 操作的推送通知服务。Expo 的基础设施设计用于至少一次交付给基础推送通知服务。在某些情况下,通知可能被 Google 或 Apple 投递多次或根本不投递,尽管这些情况很少见。

在将通知移交给基础推送通知服务后,Expo 创建一个“推送回执”,记录移交是否成功。推送回执标记基础推送通知服务是否接收了通知。

最后,Google 和 Apple 的推送通知服务根据其政策将通知投递给设备。

ExpoPushToken 何时以及为何会改变

ExpoPushToken 在应用程序升级期间保持不变。在 Android 上,重新安装应用可能会导致令牌改变。在 iOS 上,即使卸载并重新安装应用,令牌也保持不变。

如果您更改了 applicationIdexperienceId(通常是 @expoUsername/projectSlug),它也会改变。

ExpoPushToken 永不失效。但是,如果您的用户卸载了应用,您将从 Expo 的服务器收到 DeviceNotRegistered 错误。这意味着您应该停止向此令牌发送通知。

推送通知故障排除

通知无法工作

推送通知有很多移动部分,因此可能由于多种原因导致此情况。为了缩小问题范围,请检查 推送票据推送回执 中的错误消息。

您还可以通过测试 本地通知 进一步缩小范围。这确保您所有的客户端逻辑都是正确的,并将问题缩小到服务器端或应用凭据。

查看此处的快速终端命令以获取推送回执
  1. 发送通知:
curl -H "Content-Type: application/json" -X POST "https://exp.host/--/api/v2/push/send" -d '{ "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]", "title":"hello", "body": "world" }'
  1. 使用生成的票据 id 请求推送回执:
curl -H "Content-Type: application/json" -X POST "https://exp.host/--/api/v2/push/getReceipts" -d '{ "ids": [ "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" ] }'

开发时通知有效,但在发布模式下无效

这表明您可能配置了错误的凭据,或者根本没有在生产应用中配置它们。Expo Go 使用 Expo 的凭据,这使得在开发中可以处理通知。

当您为应用商店构建应用时,您需要生成并使用自己的凭据。在 Android 上,请按照 此指南 操作。在 iOS 上,由您的 推送密钥 处理(撤销与您的应用关联的推送密钥会导致您的通知无法投递。为此,请使用 eas credentials 添加新的推送密钥)。

有关更多信息,请参见 应用签名

Android 上偶尔停止接收通知

这可能与您发送的通知的 priority 级别有关。您可以了解更多关于 Android 优先级Expo 接受四种优先级

  • default:手动映射到 Apple 和 Google 文档中的默认优先级
  • high:映射到 Apple 和 Google 文档中的高优先级
  • normal:映射到 Apple 和 Google 文档中的正常优先级
  • (省略优先级):与指定 default 的效果完全相同

将优先级设置为 high 可以使您的通知在 Android 上更有可能显示。

处理过期的推送通知凭据

当您的推送通知凭据过期时,运行 eas credentials,选择 iOS 和构建配置文件,然后删除您的推送通知密钥并生成一个新的。

iOS 上没有找到有效的 aps-environment 权限字符串错误

如果您尚未为您的 iOS 项目设置推送通知密钥,则会发生此错误。要检查,请访问 项目凭据页面

要生成新的推送通知密钥,通过运行以下命令触发新构建:

Terminal
eas build --profile [profile] --platform ios

有关视觉指南,请参见 Expo 与 EAS 视频

发送通知时出现错误信息

检查返回的推送票据或回执的 details 属性以获取更多信息。 阅读此文 了解常见错误代码响应及其相关解决方案。

在 iOS 上获取推送令牌耗时较长

getDevicePushTokenAsyncgetExpoPushTokenAsync 有时在 iOS 上可能需要较长时间才能解析。这超出了 expo-notifications 的控制,正如 Apple 的 推送通知故障排除 技术说明中所述:

这不一定是错误条件。系统可能根本没有互联网连接,因为它超出了任何蜂窝塔或 Wi-Fi 接入点的范围,或者可能处于飞行模式。您的应用应正常继续运行,仅禁用依赖于推送通知的功能,而不是将其视为错误。

以下是我们社区成员解决此问题的一些方法:

阅读苹果的技术说明以排除推送通知故障

阅读苹果的 推送通知故障排除技术说明!这是此问题的单一最可靠信息来源。帮助您理解他们的建议:

稍后再试
  • 设备附近的 APNS 服务器可能因 此论坛线程 指示而宕机。出去走走,稍后再试!
  • 根据 此 GitHub 评论 的建议,再等几天再试。
禁用设备上的网络共享

您可能需要禁用网络共享,因为这可能影响注册,正如 此 Stack Overflow 答复 所建议的。

重启设备

如果您刚更改了应用应注册的 APNS 服务器(通过在同一设备上安装 TestFlight 构建来自 Xcode 构建),您可能需要根据 此 Stack Overflow 答复 重启设备。

为设备设置 SIM 卡

如果您遇到此问题的设备尚未设置 SIM 卡,则配置它可能有助于减轻此错误,正如 此 Stack Overflow 答复 所建议的。

其他事项

通过 FCM 和 APNs 直接发送通知

如果您不使用 Expo 推送通知服务,而是希望直接与 Google 和 Apple 通信,请参阅 通过 FCM 和 APNs 发送通知

Android 上的通知图标是灰色或白色方块

这表示您提供的图像资产存在问题。图像应该是全白色并带有透明背景(这是必需的,并由 Google 强制执行,而不是 Expo)。有关更多信息,请参见 这篇文章