返回

解决 Google Play RTDN 403 错误 (让 RevenueCat 恢复通知)

Android

搞定 Google Play RTDN 403 错误:让 RevenueCat 重新收到通知

哥们儿,你是不是也碰到了 Google Play Console 实时开发者通知(RTDN)发不出去,点个“发送测试通知”就给你甩个 403 错误的糟心事?更让人头大的是,配好的 Pub/Sub 愣是一个消息都收不到,下游的 RevenueCat 自然也跟着抓瞎。别急,这事儿不少人踩过坑,咱们捋一捋,看看怎么把它摆平。

啥情况?Google Play RTDN 测试通知发不出,报 403 错误

先对对症状:

  1. 场景 :你想用 Google Play 的 RTDN 功能,通过 Pub/Sub 把购买、订阅变动之类的消息实时推送到自己的后端(这里用的是 RevenueCat 作为处理服务器)。
  2. 配置自检
    • Pub/Sub 主题(Topic)创建好了,看着没毛病。
    • IAM 权限和服务账号(Service Account)也配了,感觉该给的都给了。
    • RevenueCat 那边的 Webhook URL 是公开可访问的。
  3. 问题现象
    • 在 Google Play Console 的“创收” > “创收设置”页面,点击 RTDN 配置旁边的“发送测试通知”按钮,咣当一下,弹了个 403 Forbidden 的错误。
    • 去 Google Cloud Console 查看 Google Play Android Developer API 的监控面板,在对应 Pub/Sub 主题相关的指标里,能看到类似这样的错误日志:Error calling androidpublisher.SubscriptionPurchasesV2Service.Get: Value: 100%
    • 配置给 RevenueCat 使用的那个 Pub/Sub 订阅(Subscription),一直安安静静,啥消息也收不到。
  4. 你尝试过的
    • 反复检查服务账号的 IAM 角色,确认有 Pub/Sub 发布者(Publisher)、订阅者(Subscriber,虽然主要是 RevenueCat 用,但可能也查了下)以及 Play Console API 相关的权限。
    • 核对 Pub/Sub 主题和订阅的配置信息,确认无误。
    • 手动用服务账号调用 Google Play Developer API 的其他接口,是能调通的。
    • 翻看了 Google Cloud 的日志,但没找到直接解释为啥 403 的明确线索。
    • 甚至尝试重新创建 Pub/Sub 主题和订阅,问题依旧。

理想状态下应该是啥样?

点一下测试通知,消息顺利发到 Pub/Sub 主题,然后你的订阅(连着 RevenueCat 的)收到消息,转发给 RevenueCat 的 Webhook,最后 RevenueCat 处理通知并更新用户的购买状态。

为啥会这样?扒一扒 403 错误的根源

遇到 403 错误,十有八九跟权限脱不了干系。但具体是哪里的权限出了问题,可能性还挺多的。结合 androidpublisher.SubscriptionPurchasesV2Service.Get 这个错误信息,我们可以大胆猜测一下:

  1. 核心权限缺失: Play Console 代表你(或者你指定的 Service Account)向 Pub/Sub 发布消息,它需要有对应 Topic 的 roles/pubsub.publisher 权限。这是最基础的,但有时候可能配错了账号或者配到了错误的项目上。
  2. Play Console 内部验证失败: 那个 SubscriptionPurchasesV2Service.Get 错误比较蹊跷。它暗示 Play Console 在发送 RTDN 之前,可能尝试调用了 Play Developer API 的某个接口(比如获取订阅信息 V2 版的 Get 方法)来做某种验证或准备工作。如果这个 内部调用 失败了(报 403),那么后续的 发布到 Pub/Sub 操作也就被阻止了,最终体现为你点击按钮时看到的那个 403。这个内部调用可能是用的 Google 自己的服务账号,也可能是用了你配置的那个服务账号,权限如果不够,就会卡住。
  3. 服务账号绑定问题: 在 Play Console 的 API 访问权限页面,你可能需要关联一个 GCP 项目,并可能指定一个服务账号来访问 Google API。这里选择的服务账号,以及它在关联 GCP 项目里的权限,都需要正确无误。是不是选错了服务账号?或者服务账号没给够权限?
  4. Pub/Sub 主题策略限制: 虽然不常见,但 Pub/Sub 主题本身也可能有资源策略(Resource Policy)限制了谁可以发布。
  5. API 未启用: 确保关联的 GCP 项目里,Google Play Android Developer APICloud Pub/Sub API 都已经启用。虽然手动调用其他 API 成功了,但不代表所有环节依赖的 API 都开了。
  6. 项目关联错误: Play Console 账户关联的 GCP 项目和你创建 Pub/Sub 主题、配置服务账号权限的 GCP 项目,是同一个吗?别搞混了。
  7. Google Cloud 配置延迟: 极少数情况下,IAM 策略或 API 配置的生效需要一点时间(几分钟到十几分钟不等)。

怎么办?一步步排查和解决

别慌,我们一项项来检查。

一级

权限问题是 403 的重灾区,务必仔细检查。

1. 检查 Play Console 用来发消息的“身份”

Google Play Console 发布 RTDN 时,有两种可能的身份:

  • 默认 Google 管理的服务账号 :格式通常是 google-play-developer-notifications@system.gserviceaccount.com。这个账号理论上应该由 Google 自动管理权限,但有时也会出问题。
  • 你指定的服务账号 :如果你在 Play Console 的 API 访问页面为 RTDN 功能明确指定了一个你创建的服务账号。

操作步骤:

  • 确定身份 :去 Play Console -> 设置 -> API 访问权限。看看 RTDN 配置那里有没有让你指定服务账号。如果没有,大概率是用 Google 默认的。如果有,就用你指定的那个。

2. 检查 Pub/Sub 主题的发布权限

目标 Pub/Sub 主题需要允许上述“身份”有发布消息的权限 (roles/pubsub.publisher)。

操作步骤 (GCP Console):

  • 打开 Google Cloud Console,导航到你的项目。
  • 进入 “Pub/Sub” -> “主题”。
  • 找到你为 RTDN 创建的那个主题,选中它。
  • 在右侧信息面板,点击“权限”标签页(或者类似的管理权限入口)。
  • 查看“主账号”列表里:
    • 如果你用的是 Google 默认账号 ,确认 google-play-developer-notifications@system.gserviceaccount.com 这个账号(或者类似的,具体名字可能有细微差别)在列表里,并且具有 Pub/Sub 发布者 (Pub/Sub Publisher) 角色。如果不在,手动添加它,并授予该角色。
    • 如果你用的是 你指定的服务账号 ,确认你那个服务账号的邮件地址(比如 your-service-account-name@your-project-id.iam.gserviceaccount.com)在列表里,并且具有 Pub/Sub 发布者 角色。如果不在或角色不对,添加/修改。

操作步骤 (gcloud 命令行):

# 替换 YOUR_TOPIC_ID 为你的主题 ID
# 替换 YOUR_PROJECT_ID 为你的 GCP 项目 ID
# 替换 SERVICE_ACCOUNT_EMAIL 为你需要检查权限的服务账号邮箱地址 (Google 默认的或你自建的)

gcloud pubsub topics get-iam-policy projects/YOUR_PROJECT_ID/topics/YOUR_TOPIC_ID --format json

检查返回的 JSON 中,bindings 数组里是否有针对 roles/pubsub.publisher 的条目,其 members 列表里是否包含你要检查的 serviceAccount:SERVICE_ACCOUNT_EMAIL

如果没有,用以下命令添加权限:

gcloud pubsub topics add-iam-policy-binding projects/YOUR_PROJECT_ID/topics/YOUR_TOPIC_ID \
    --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
    --role="roles/pubsub.publisher"

安全建议:

  • 坚持 最小权限原则 。只给必要的 pubsub.publisher 权限,不要图省事给 Owner 这种大权限。
  • 如果你用的是自定义服务账号,保管好它的密钥文件(如果下载了的话),不要泄露。

进阶使用技巧:

  • IAM 权限的生效可能需要几分钟。改完权限后,稍等片刻再试。
  • 确认操作的 GCP 项目是 Play Console 账户关联的那个项目。

一级

虽然你可能检查过了,但魔鬼在细节中。

1. 核对 Topic 和 Subscription 名称

  • Play Console 配置 :在 Play Console 的 RTDN 设置里填写的 Pub/Sub 主题名称 ,必须是完整的格式:projects/YOUR_PROJECT_ID/topics/YOUR_TOPIC_ID。检查拼写、项目 ID 和主题 ID 是否完全正确。
  • RevenueCat 配置 :在 RevenueCat 后台配置 Google RTDN 时,它通常需要你提供 Pub/Sub 订阅名称 (Subscription Name) 。这个订阅必须是已经 在 GCP Pub/Sub 里创建好,并且关联到 上述 Play Console 指定的那个主题的。确保 RevenueCat 配置里的订阅名和你实际创建的订阅名(同样是完整格式:projects/YOUR_PROJECT_ID/subscriptions/YOUR_SUBSCRIPTION_ID)一致。

操作步骤 (GCP Console):

  • 导航到 Pub/Sub -> 主题,确认你的主题存在且名称正确。
  • 导航到 Pub/Sub -> 订阅,找到你为 RevenueCat 创建的订阅。
    • 确认它的名称 (Subscription ID)。
    • 确认它关联的“主题名称”是你配置给 Play Console 的那个主题。
    • 确认订阅类型:RevenueCat 一般推荐使用 推送 (Push) 类型,并且推送端点 (Endpoint URL) 指向 RevenueCat 提供的那个 URL。如果是拉取 (Pull),需要 RevenueCat 侧支持并配置好拉取。检查 RevenueCat 的文档确认它需要哪种类型以及具体配置。

操作步骤 (gcloud 命令行):

# 查看主题详情
gcloud pubsub topics describe projects/YOUR_PROJECT_ID/topics/YOUR_TOPIC_ID

# 查看订阅详情
gcloud pubsub subscriptions describe projects/YOUR_PROJECT_ID/subscriptions/YOUR_SUBSCRIPTION_ID

检查输出里的名称、关联主题、推送配置等信息。

进阶使用技巧:

  • 为 Pub/Sub 订阅配置死信主题 (Dead-letter topic) 。这样一来,如果消息因为某些原因(比如推送失败次数过多)无法被 RevenueCat 正确处理,它们会被转发到死信主题,方便你排查问题,避免消息丢失。

一级

基础设置也不能忽略。

1. 检查关联的 GCP 项目

  • Play Console :设置 -> 开发者账号 -> API 访问权限。确认这里链接的 Google Cloud 项目 就是你创建 Pub/Sub、配置服务账号权限的那个项目。如果链接了错误的项目,或者没有链接项目,RTDN 可能无法正常工作。

2. 检查必要的 API 是否启用

  • Google Cloud Console :导航到 “API 和服务” -> “库 (Library)”。
  • 搜索并确认以下两个 API 在你的关联项目中处于 启用 (Enabled) 状态:
    • Google Play Android Developer API
    • Cloud Pub/Sub API
  • 如果未启用,点击启用它们。

操作步骤 (gcloud 命令行):

# 列出已启用的服务,检查列表里是否有 pubsub.googleapis.com 和 androidpublisher.googleapis.com
gcloud services list --enabled --project=YOUR_PROJECT_ID

进阶使用技巧:

  • 有时候,GCP 项目和 Play Console 之间的关联可能“卡住”。尝试解除关联再重新关联 GCP 项目可能会有奇效。注意:解除关联可能会影响其他依赖此关联的功能。
  • 确保你的 GCP 项目结算功能是正常的 。虽然测试通知免费,但如果项目因欠费等原因被暂停,API 调用会失败。

一级

虽然 403 发生在 Google 端,但最终目标是让 RevenueCat 收到消息,所以也要确认一下 RevenueCat 的设置。

  • 遵循 RevenueCat 文档 :务必严格按照 RevenueCat 官方提供的 Google RTDN 设置指南进行操作。他们的文档通常会非常详细地说明需要在 GCP 和 RevenueCat 两边完成哪些步骤。
  • 核对订阅名 :再次确认你在 RevenueCat 里填写的 Pub/Sub 订阅名称 是准确无误的、完整的 GCP 资源名。
  • 检查 RevenueCat 状态 :登录 RevenueCat 控制面板,查看是否有关于 Google 集成状态的提示或错误信息。

操作步骤:

  • 找到 RevenueCat 关于 Google Real-time Developer Notifications 的设置页面。
  • 仔细比对页面上显示的需要配置的项(比如 Pub/Sub Subscription Name)和你自己在 GCP 里的实际配置。

一级

这个错误提示是关键线索,指向 Play Developer API 的调用问题。如前所述,这可能是 Play Console 在发 RTDN 前的内部检查步骤失败了。

可能原因及解决方案:

  1. Play Console 内部服务账号权限问题 :Google 可能需要给 google-play-developer-notifications@system.gserviceaccount.com 这个(或类似的内部账号)授予访问 androidpublisher.googleapis.com API 的特定权限,但因为某种原因没有正确配置。这种情况你通常无能为力,需要联系 Google Play Console 支持。
  2. 你指定的 Service Account 缺少 Play API 权限 :如果你在 Play Console API 访问设置里,为 RTDN 指定了你自己的服务账号,那么除了 roles/pubsub.publisher 之外,这个服务账号可能还需要访问 Play Developer API 的权限。虽然听起来有点绕(为啥发通知需要读订阅?),但结合错误信息来看,值得一试。
    • 尝试添加角色 :给你的服务账号添加 roles/monitoring.viewer (监控查看者,可能包含某些只读 API 权限),或者一个更精确的、包含 androidpublisher.subscriptionsv2.get 权限的自定义角色(如果 Google 文档有说明的话)。甚至可以临时给个宽泛点的角色(如 roles/viewer 项目观察者,或者 Play Console 相关角色像“财务角色”),测试是否能解决 403,成功后再收紧权限

操作步骤 (GCP Console):

  • IAM & Admin -> IAM。
  • 找到你指定用于 RTDN 的那个服务账号。
  • 点击编辑(铅笔图标),添加角色。搜索并添加上述建议的角色。

操作步骤 (gcloud 命令行):

gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
    --member="serviceAccount:YOUR_SERVICE_ACCOUNT_EMAIL" \
    --role="roles/monitoring.viewer" # 或者其他尝试的角色

安全建议:

  • 给服务账号添加权限要谨慎。特别是像 Viewer 这样比较宽泛的角色,测试完成后,如果问题解决,应尽可能换成更精确的权限。

何时联系支持?

  • 如果你确认 Pub/Sub 发布权限没问题,API 都启用了,项目关联也正确,但依然收到 403,特别是伴随着那个 SubscriptionPurchasesV2Service.Get 错误。
  • 这种情况很可能是 Play Console 后端或其内部服务账号的配置问题。准备好你的 App 包名、GCP 项目 ID、Pub/Sub 主题名称、你遇到的错误截图、错误日志里的 trackingId (如果有的话),通过 Play Console 的帮助中心联系 Google 支持,详细说明你遇到的问题和已经尝试过的排查步骤。

排查这种跨平台、涉及多个服务和权限的问题确实有点烧脑。耐心一点,按照上面的思路一步步来,多半能找到症结所在。祝你好运!