文档 / 搜索 / LingCode Cloud / 推送通知
📘 参考 ● 进阶 更新于 2026-06-11

推送通知

一句话:Web Push 让你即使在应用标签页已经关闭时也能通知用户。它就是浏览器标准的 Web Push(VAPID)流程——需要 HTTPS、一个 service worker,以及用户授权。SDK 的 client.push 在浏览器里做两件事:用 isSupported() 做能力检测,用 subscribe() 注册你的 service worker、弹出权限提示,并把用户的订阅对象存到后端。发送通知是另一个独立的服务端步骤——你从函数托管应用向已存储的订阅对象推送,而不是从浏览器发送。

大多数人想要的「通知」其实是看似一体、实则两半的东西。浏览器这一半的关键是赢得授权并捕获送达地址——这发生在你的页面里,用户就在旁边看着。送达那一半,则是某件事真正发生时,由服务器去戳那个已保存的地址。LingCode Cloud 处理掉中间那段尴尬的衔接:它把每个用户的订阅对象绑定到其账号上存起来,这样标签页早已关闭后你依然能触达他们。本页把浏览器这一半从头讲到尾,并指引你去看服务端那一半。

为什么是这样设计

推送通知必须在你的代码没有运行时送达——用户几小时前就关掉了标签页。正因如此,标准要求一开始就具备三样东西:

要订阅,浏览器还需要你后端的 VAPID 公钥——这个身份让推送服务能信任那些声称来自你的推送确实来自你。LingCode Cloud 替你管理这个密钥;SDK 在底层把它取回来。订阅创建后,它会存到后端并绑定到已登录用户,这样你之后才能精准触达他们。

容易把人绊倒的那个分界

浏览器负责订阅;服务器负责发送。你无法从刚刚调用了 subscribe() 的那个页面发出通知——页面只捕获了地址而已。真正推送一条消息,是从函数托管应用在服务端向用户已存储的订阅对象发起。先把订阅流程搭好,确认那行记录确实落库,再去接通发送。

浏览器侧的流程

/try 和 Mac 预览里,window.lingcode 已经存在。在你自己的应用里,先创建客户端(参见总览),再跑下面这三步。

先做能力检测

并非每个浏览器或上下文都能做推送。在展示任何「启用通知」UI 之前先检查一下——提供一个根本无法工作的按钮没有意义。

if (!lingcode.push.isSupported()) {
  // 隐藏你的「启用通知」按钮——这里不支持推送。
  return;
}

isSupported() 同步返回一个布尔值。

为用户订阅

在用户手势(例如点击按钮)的响应中调用 subscribe()。它会注册你的 service worker,通过浏览器的 PushManager 订阅,并把订阅对象按当前用户存到后端。这个调用会触发浏览器的权限提示。

const { data, error } = await lingcode.push.subscribe({
  serviceWorker: '/sw.js'
});

if (error) {
  // 用户拒绝了授权,或这里不支持推送——优雅降级。
  console.warn('Could not enable push:', error);
} else {
  // 订阅对象已存到服务端;现在可以触达该用户了。
}

opts 参数是可选的;{ serviceWorker?: string } 指向你的 service worker 文件。每个调用都返回 { data, error }

从服务器发送

这一步在浏览器里发生。一旦订阅对象被存好,就从函数托管应用——任何能在服务端触达用户已存储订阅对象的地方——向它推送一条消息。浏览器唯一的活儿就是捕获授权和送达地址;在那之后的一切,都由你的后端在某件事真正发生时触发。

你必须发布一个 service worker。推送送达要经过它——没有 /sw.js(或你传给 subscribe() 的任意路径)就没有推送。确保该文件确实在你引用的那个路径上、同源地提供出来。

底层细节(REST)

SDK 封装了两个端点。你很少直接调用它们,但了解其结构在调试时很有帮助。

取回 VAPID 公钥

浏览器在能订阅之前需要后端的 VAPID 公钥。SDK 替你取回:

GET https://lingcode.dev/api/cloud/be/<backend-id>/push/vapid-public

→ { "key": "<vapid-public-key>" }

存储一个订阅对象

当浏览器的 PushManager 产出一个订阅对象后,SDK 把它 POST 到后端,按当前用户存起来:

POST https://lingcode.dev/api/cloud/be/<backend-id>/push/subscribe

{
  "subscription": {
    "endpoint": "https://<push-service>/...",
    "keys": {
      "p256dh": "<client-public-key>",
      "auth": "<auth-secret>"
    }
  }
}

错误

要求与坑点

推送在哪里能用

仅限 HTTPS。它在你托管应用的安全 URL 上可用——*.run.lingcode.dev 或你的自定义域名——以及用于开发的 http://localhost。任何其它主机上的纯 http:// 都不支持推送。

授权是按用户来的,且可撤销。用户为你的来源(origin)授权,并且可以随时在浏览器设置里撤销——你的代码不会被告知。始终用 isSupported() 做能力检测,并处理未授权的情况(来自 subscribe()error),而不是假定订阅对象一定存在。