This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

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

编辑页面

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


设置 expo-notifications 库和 Expo 推送通知服务时常见问题及常见问答。

Expo 推送通知服务 FAQ

推送通知服务的费用

通过 Expo 推送通知服务发送通知不收取任何费用。

发送通知的限制

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

为获得最佳效果,我们建议你在服务器中添加限流(expo-server-sdk-node 中已自动处理,见 expo-server-sdk-node)和重试逻辑。

使用 Expo 推送通知服务不是必须的

你可以将任何推送通知服务用于 Expo 项目。expo-notifications 中的 getDevicePushTokenAsync 方法允许你获取原生设备推送令牌,然后将其用于其他服务,或者甚至直接通过 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. 使用返回的 ticket id 请求推送回执:
curl -H "Content-Type: application/json" -X POST "https://exp.host/--/api/v2/push/getReceipts" -d '{ "ids": [ "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" ] }'

开发环境可用,但正式版不可用

这表明你的凭证配置有误,或者在生产应用中根本没有配置凭证。在 SDK 53 及更高版本中,Expo Go 不支持推送通知功能,因此要测试推送,你应该使用 开发构建。在 SDK 52 及更早版本中,Expo Go 使用的是 Expo 的凭证,因此无需配置你自己的凭证也能在开发环境中正常使用推送通知。

当你为应用商店构建应用时,需要生成并使用自己的凭证。在 Android 上,请参照本指南。在 iOS 上,这由你的 推送密钥处理(吊销与你的应用关联的推送密钥会导致通知投递失败。要修复它,请使用 eas credentials 添加新的推送密钥)。

更多信息请参见 应用签名

Android 上通知偶尔停止推送

这很可能与你发送的通知的 priority 级别有关。你可以了解更多关于 Android 优先级 的信息。Expo 支持四种优先级

  • default:手动映射为 Apple 和 Google 文档中定义的默认优先级
  • high:映射为 Apple 和 Google 文档中定义的高优先级
  • normal:映射为 Apple 和 Google 文档中定义的普通优先级
  • (未省略 priority):完全按指定 default 处理

将优先级设置为 high 会让你的通知在 Android 上显示的可能性最大。

处理已过期的推送通知凭证

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

iOS 上出现 No valid aps-environment entitlement string found 错误

如果你尚未为 iOS 项目设置推送通知密钥,就会出现此错误。要检查这一点,请前往 项目凭证页面

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

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

如需可视化指南,请查看 使用 EAS 配置 Expo 通知的视频

发送通知时的错误信息

查看返回的推送票据或回执的 details 属性以获取更多信息。在此处阅读常见错误码响应及其对应的解决方案。

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

getDevicePushTokenAsyncgetExpoPushTokenAsync 在 iOS 上有时可能需要很长时间才能完成。这不在 expo-notifications 的控制范围内,正如 Apple 的《排查推送通知问题》技术说明中所述:

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

阅读 Apple 关于排查推送通知问题的技术说明

阅读 Apple 的关于排查推送通知问题的技术说明!这是关于此问题最可靠的信息来源。为了帮助你理解他们的建议:

稍后再试一次
  • 设备附近的 APNS 服务器可能宕机了,如此论坛帖子所示。出去走走,稍后再试!
  • 按照此 GitHub 评论的建议,几天后再试。
在设备上关闭网络共享

你可能需要关闭网络共享,因为按此 Stack Overflow 回答所述,这可能会影响注册。

重启你的设备

如果你刚刚更改了应用应注册到的 APNS 服务器(例如,在同一设备上用 TestFlight 构建覆盖了 Xcode 构建),按此 Stack Overflow 回答所述,你可能需要重启设备。

使用 SIM 卡设置你的设备

如果出现此问题的设备尚未使用 SIM 卡完成设置,根据此 Stack Overflow 回答的说法,配置它可能有助于缓解此问题。

其他

通过 FCM 和 APNs 直接发送通知

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

Android 上的通知图标显示为灰色或白色方块

这表明您提供的图像资源存在问题。图像应为纯白色,并带有透明背景(这是 Google 的要求,由 Google 强制执行,而非 Expo)。如需更多信息,请参阅这篇文章