← 返回博客
Diagram of an Android PWA push notification travelling from a cloud push service through a service worker to a phone notification tray

Android PWA 推送通知完全指南:原理、配置与故障排查(2026)

Android PWA 推送通知完全指南:原理、配置与故障排查(2026)

推送是为数不多完全由自己掌握的留存渠道。对于用 PWA 而不是 APK 做安卓分发的团队,第一个问题几乎总是同一个:Android 上的 PWA 推送通知到底能不能用,和原生 App 的推送差多少?

简短的回答是:在安卓上完全可用,而且已经稳定了很多年,与原生推送的差距比多数人以为的要小得多。展开说,整套机制有三个环节,而绝大多数「推送突然不工作了」最后都能追溯到其中之一。

Android PWA 推送通知到底是什么

PWA 推送通知,是由浏览器的推送服务把消息投递到设备、再由 Service Worker 负责展示的一条通知——即使站点已经关闭也能收到。在安卓上,Chrome 及其他 Chromium 内核浏览器会把它显示在系统通知栏里,形态和原生 App 通知完全一致:图标、标题、正文、操作按钮,点击后打开你的站点。

从这个定义能推出两件比任何实现细节都更重要的事:

  • 接收消息的是 Service Worker,不是页面。 用户不需要开着标签页。这正是推送能成为留存渠道、而不只是页面上一个小组件的原因。
  • 投递要经过浏览器厂商的推送服务。 你永远不直接和设备通信,而是把加密后的负载交给一个 endpoint,剩下的由推送服务完成。

必须做对的三个环节

一个注册成功的 Service Worker

推送要求在 HTTPS 下有一个处于激活状态的 Service Worker。如果注册失败——scope 写错、脚本 MIME 类型不对、缓存里留着旧版本——后面所有环节都不成立。scope 还决定了这个 worker 控制哪些 URL,所以注册在 /app/sw.js 的 worker 不会为 /app/ 之外的页面提供推送。

带 VAPID 密钥的订阅对象

浏览器会生成一个订阅对象,里面包含 endpoint 地址和两个加密密钥。你只需生成一次 VAPID 密钥对,订阅时把公钥交给浏览器,发送时用私钥签名。需要在服务端保存的就是这个订阅对象——可以把它理解成用户的「地址」。

订阅会过期、会轮换。生产系统必须有 pushsubscriptionchange 的处理逻辑,以及一个定期清理返回 404 / 410 的 endpoint 的任务,否则投递量会在几个月里悄无声息地一路下滑。

推送服务与发送端

订阅对象里的 endpoint 指向浏览器厂商的基础设施。你的服务器用订阅里的密钥加密负载,然后 POST 过去。多数团队会用现成的库而不是手写这套加密——因为消息加密写错时,得到的往往是静默的投递失败,而不是一条有用的报错。

决定订阅率的是权限弹窗

上面都是管道。真正决定可触达用户规模的,是有多少访客授予了通知权限,而这件事在会话开始的几秒钟内就被决定了。

安卓 Chrome 只允许在用户手势触发时弹出权限请求,而且一次拒绝几乎是永久的——用户必须自己进站点设置才能改回来。这种不对称性应该直接反映到流程设计上:

  • 绝不在页面加载时弹窗。 对首次访问者冷启动弹权限,是订阅率低的头号原因,而且每一次拒绝都意味着这个用户你再也问不了第二次。
  • 在用户已经感受到价值之后再问,而不是之前。一个刚刚查了订单或收藏了商品的访客,才明白自己订阅的是什么。
  • 先用软性预弹窗。 你自己的页内说明被拒绝的成本是零;浏览器的原生弹窗被拒绝,代价是永久失去这个用户。只对在你的预弹窗里点了「好」的人,才触发真正的权限请求。
  • 说清楚发什么、多久发一次。「仅发送订单状态更新」的转化率好过「开启通知」,而且能降低后续的退订。

Android PWA 推送与原生推送的差别

对大多数产品场景来说功能差距很小,但并非没有:

对比项

Android PWA 推送

原生安卓推送

是否必须安装才能收

否——浏览器里完成订阅即可

投递路径

浏览器推送服务

App 层消息 SDK

富媒体与操作按钮

支持(图片、按钮、角标)

支持

后台处理

Service Worker,受浏览器生命周期约束

系统级服务

清除浏览器数据后是否存活

除非清除 App 数据,否则存活

实际影响是:PWA 的订阅相对更易流失。用户清除浏览器数据就会丢掉订阅,而清数据的频率远高于卸载 App。所以要把「重新订阅」当成常态来设计,而不是假设订阅永久有效;考核指标看活跃 endpoint 数,别看累计订阅数。

如果你还在决策分发方式本身,推送之外的取舍可以看 PWA 与 APK 的差异 以及更完整的 PWA 与原生 App 对比

Android PWA 推送通知失效的常见原因

推送出问题时,基本是下面这几种,大致按出现频率排列:

  1. 订阅过期了但从未刷新。 没有 pushsubscriptionchange 处理、没有清理任务。表现:投递率在数周内缓慢衰减。
  2. Service Worker 被替换或注销了。 某次发版改了 worker 的路径或 scope。表现:所有推送在发版那一刻同时失效。
  3. 权限是在另一个域名下授予的。 通知权限按 origin 隔离。从子域名换到主域名、或新增域名,权限状态都从零开始。
  4. 负载加密失败。 轮换后 VAPID 密钥对不匹配。表现:推送服务什么都不收,endpoint 返回 401 或 403。
  5. 设备级的省电限制。 部分安卓厂商对浏览器后台活动限制得非常激进。表现是通知延迟而不是丢失,并且集中在特定品牌机型上。
  6. 用户在系统层面把浏览器的通知静音了。 代码里查不到任何线索——只能从「发送成功数」与「实际打开数」之间的缺口看出来。

最省时间的排查顺序是:先确认推送服务是否接收了这条消息,再确认 Service Worker 是否被唤起,最后确认通知是否被展示。这是三个不同的失败面,把它们混为一谈正是推送问题排查久拖不决的原因。

该看哪些数据

只看订阅率是虚荣指标。真正值得跟踪的是这几个:

  • 弹窗授权率——反映你的时机选择和预弹窗设计好不好。
  • 活跃 endpoint 数——没有返回 404/410 的订阅,也就是真实可触达规模。
  • 发送成功数 vs 实际展示数——两者的差距来自设备与系统行为。
  • 分消息类型的点击率——这个数会告诉你是不是发得太频繁了。

常见问题

Android 上不安装 PWA 能收到推送通知吗?

可以。在安卓上,用户只要在浏览器里授予了通知权限,不把 PWA 添加到主屏幕也能收到推送。安装会让体验更好——点击通知打开的是独立窗口而不是浏览器标签页——但它不是收到推送的前提条件。

iOS 上的 PWA 推送也能用吗?

能,但仅限用户已添加到主屏幕的 PWA,且配置要求比安卓严格。如果推送是留存计划的核心,建议把安卓和 iOS 当成两次独立的推进来规划,它们的订阅经济账并不一样。

发多频繁用户才不会退订?

没有一个放之四海皆准的数字,但规律是稳定的:用户对交易类消息的容忍度远高于广播类。按行为做分层、把广播类发送控制在低频的团队,活跃 endpoint 能守得住;对所有人每周群发同一条消息的团队,endpoint 通常会持续衰减。

为什么有些安卓机型收到通知会延迟?

几乎都是厂商的省电策略限制了浏览器的后台活动。这个现象集中在特定品牌上,在 Web 层面无法控制,最好的应对方式是:不要让时效性强的消息依赖精确的到达时间。

小结

Android 上的 PWA 推送通知已经是可用于生产的能力,技术链路——Service Worker、VAPID 订阅、发送端——也早已成熟。真正决定这个渠道值不值钱的,不是管道,而是权限请求的那一刻,以及之后的发送克制。把弹窗时机做对、把失效 endpoint 清干净、用活跃可触达量而不是累计订阅数来考核。

对于走 Web 而非应用商店做安卓分发的团队,ROIBest 覆盖了这套链路的其余环节。

ROIBest

用 ROIBest 打造下一阶段增长引擎

联系我们,获取稳定、高转化的安卓 PWA 解决方案。