← 所有指南

推送通知

推送通知集成指南

通过 Hibira Push 向 iOS、Android 和浏览器发送通知。API 与 Beams 兼容:官方 Beams 服务端 SDK 只需指向你的端点即可使用,我们的客户端 SDK 是 Beams SDK 的分支,可自定义主机。

登录后,这些代码片段会换成你自己的端点,应用页面还会填入你的实例 ID。 登录

工作原理

  • 在门户的应用页面开启推送通知,即可获得实例 ID、密钥和端点。
  • 每台设备或浏览器通过客户端 SDK 注册并订阅兴趣(interest),例如 news 或 order-1024 这类主题。你的服务器推送给兴趣;设备关联已登录用户后,也可以推送给用户 ID。
  • 实例 ID 和端点放进你的 App。密钥可以推送给所有设备:请只放在服务器的 HIBIRA_PUSH_SECRET_KEY 环境变量中,绝不要放进 App 或代码仓库。
  • 每个套餐都包含推送。套餐决定可注册的设备和浏览器数量,以及推送速度。

1. 上传凭据

Apple(APNs)
在 Apple Developer 中打开 Certificates, Identifiers & Profiles › Keys,创建启用 Apple Push Notifications service(APNs)的密钥并下载 .p8 文件。在应用页面的“推送通知 › Apple(APNs)”中填写密钥 ID、团队 ID 和 App 的 Bundle ID,选择环境并上传 .p8 文件。 从 Xcode 运行的构建请选“开发环境(沙盒)”,TestFlight 和 App Store 构建请选“生产环境”。
Android(FCM)
在 Firebase 控制台打开“项目设置 › 服务账号”,点击“生成新的私钥”。把 JSON 文件上传到“推送通知 › Android(FCM)”,并把同一项目的 google-services.json 加入你的 Android App。
Web Push
无需上传:开启推送时会自动创建 VAPID 密钥。你的网站必须通过 HTTPS 提供(开发时可用 localhost)。

密钥和服务账号会加密存储,之后不会再显示。

2. 注册设备和浏览器

客户端 SDK

平台

Chrome、Edge、Firefox、Opera 和 Safari 16.4 及以上,使用标准 Web Push 和 Service Worker。 @hibira-io/push-web ↗

  1. 安装

    npm install @hibira-io/push-web
  2. 添加 Service Worker

    // public/service-worker.js, served at https://your-site/service-worker.js
    importScripts('https://cdn.jsdelivr.net/npm/@hibira-io/push-web@1/dist/service-worker.js');
    self.HibiraPush.endpoint = 'https://ws.hibira.io';
  3. 注册浏览器

    import { Client } from '@hibira-io/push-web';
    
    const push = new Client({
      instanceId: 'YOUR_INSTANCE_ID',
      endpoint: 'https://ws.hibira.io',
    });
    
    // Browsers only show the permission prompt after a click or tap.
    document.querySelector('#enable-notifications').addEventListener('click', async () => {
      await push.start();
      await push.addDeviceInterest('hello');
    });
  4. 关联已登录用户

    import { TokenProvider } from '@hibira-io/push-web';
    
    // After sign-in. Your backend answers GET /push/user-token?user_id=... (see the server guide).
    await push.setUserId(currentUser.id, new TokenProvider({ url: '/push/user-token' }));
    
    // On sign-out, so the next person on this browser doesn't get their notifications.
    await push.stop();
Web 的 Agent 提示词

粘贴到 Claude Code、Cursor、GitHub Copilot 或其他 AI 编程 Agent。提示词包含实例 ID 和端点;密钥保持为环境变量。

Add Hibira push notifications to this Web project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the Hibira client SDK (here: @hibira-io/push-web, https://github.com/hibira-io/hibira-push-web).

Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- No secret key: it belongs on the server, never in this app

What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Install @hibira-io/push-web (it replaces @pusher/push-notifications-web; the API is the same apart from the import and the endpoint option).
3. Serve service-worker.js from the site root (for example public/service-worker.js in Vite, Next.js or Create React App) with the importScripts line and the endpoint from the reference.
4. Create one shared push client module and call start() from a user action such as an "Enable notifications" button, never on page load: browsers block permission prompts that are not triggered by a click.
5. If the app has signed-in users, call setUserId with a TokenProvider pointing at the backend token endpoint after sign-in, and stop() on sign-out.
6. Web Push needs HTTPS (localhost is fine for development); on iPhone and iPad it works only once the site is added to the Home Screen.
7. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent).
8. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
9. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
10. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
11. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.

Reference setup from the Hibira push notifications guide (adapt it to the project's structure):

Install:

```shell
npm install @hibira-io/push-web
```

Add the service worker:

```js
// public/service-worker.js, served at https://your-site/service-worker.js
importScripts('https://cdn.jsdelivr.net/npm/@hibira-io/push-web@1/dist/service-worker.js');
self.HibiraPush.endpoint = 'https://ws.hibira.io';
```

Register the browser:

```js
import { Client } from '@hibira-io/push-web';

const push = new Client({
  instanceId: 'YOUR_INSTANCE_ID',
  endpoint: 'https://ws.hibira.io',
});

// Browsers only show the permission prompt after a click or tap.
document.querySelector('#enable-notifications').addEventListener('click', async () => {
  await push.start();
  await push.addDeviceInterest('hello');
});
```

Link the signed-in user:

```js
import { TokenProvider } from '@hibira-io/push-web';

// After sign-in. Your backend answers GET /push/user-token?user_id=... (see the server guide).
await push.setUserId(currentUser.id, new TokenProvider({ url: '/push/user-token' }));

// On sign-out, so the next person on this browser doesn't get their notifications.
await push.stop();
```

3. 从服务器推送

服务器 SDK

语言

用官方 Beams 服务端 SDK 从 Node.js 推送,只需指向你的端点。 @pusher/push-notifications-server ↗

  1. 安装

    npm install @pusher/push-notifications-server
  2. 推送给兴趣(interest)

    const PushNotifications = require('@pusher/push-notifications-server');
    
    const beams = new PushNotifications({
      instanceId: 'YOUR_INSTANCE_ID',
      secretKey: process.env.HIBIRA_PUSH_SECRET_KEY,
      endpoint: 'ws.hibira.io',
    });
    beams.protocol = 'https'; // the SDK switches to http when an endpoint is set
    
    await beams.publishToInterests(['hello'], {
      apns: { aps: { alert: { title: 'Hello', body: 'Hello, world!' } } },
      fcm: { notification: { title: 'Hello', body: 'Hello, world!' } },
      web: { notification: { title: 'Hello', body: 'Hello, world!', deep_link: 'https://your-site.example/' } },
    });
  3. 添加用户令牌端点

    // Express: the client SDKs call GET /push/user-token?user_id=...
    app.get('/push/user-token', requireLogin, (req, res) => {
      if (req.query.user_id !== String(req.user.id)) return res.sendStatus(401);
      res.json(beams.generateToken(String(req.user.id))); // { token: '...' }
    });
  4. 推送给已登录用户

    await beams.publishToUsers(['user-1'], {
      apns: { aps: { alert: { title: 'Order shipped', body: 'Order #1024 is on its way.' } } },
      fcm: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
      web: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
    });
Node.js 的 Agent 提示词

粘贴到 Claude Code、Cursor、GitHub Copilot 或其他 AI 编程 Agent。提示词包含实例 ID 和端点;密钥保持为环境变量。

Add Hibira push notifications to this Node.js project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the official Beams server SDKs pointed at the Hibira endpoint (here: @pusher/push-notifications-server, https://github.com/pusher/push-notifications-node).

Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- Secret key: read it from the HIBIRA_PUSH_SECRET_KEY environment variable (server-side only)

What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Create one shared module that builds the PushNotifications client from environment variables, with the endpoint option and beams.protocol set as in the reference (without them the SDK talks to pusher.com, or to the endpoint over plain http).
3. If the app has signed-in users, add the token route behind the project's existing authentication middleware; it must refuse a user_id that is not the signed-in user's.
4. Publish from the places that should notify (jobs, controllers, event handlers) through the shared module, and log the publish ID it returns.
5. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent). Never commit the secret key or send it to a browser or mobile app.
6. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
7. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
8. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
9. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.

Reference setup from the Hibira push notifications guide (adapt it to the project's structure):

Install:

```shell
npm install @pusher/push-notifications-server
```

Publish to an interest:

```js
const PushNotifications = require('@pusher/push-notifications-server');

const beams = new PushNotifications({
  instanceId: 'YOUR_INSTANCE_ID',
  secretKey: process.env.HIBIRA_PUSH_SECRET_KEY,
  endpoint: 'ws.hibira.io',
});
beams.protocol = 'https'; // the SDK switches to http when an endpoint is set

await beams.publishToInterests(['hello'], {
  apns: { aps: { alert: { title: 'Hello', body: 'Hello, world!' } } },
  fcm: { notification: { title: 'Hello', body: 'Hello, world!' } },
  web: { notification: { title: 'Hello', body: 'Hello, world!', deep_link: 'https://your-site.example/' } },
});
```

Add the user token endpoint:

```js
// Express: the client SDKs call GET /push/user-token?user_id=...
app.get('/push/user-token', requireLogin, (req, res) => {
  if (req.query.user_id !== String(req.user.id)) return res.sendStatus(401);
  res.json(beams.generateToken(String(req.user.id))); // { token: '...' }
});
```

Publish to a signed-in user:

```js
await beams.publishToUsers(['user-1'], {
  apns: { aps: { alert: { title: 'Order shipped', body: 'Order #1024 is on its way.' } } },
  fcm: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
  web: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
});
```

4. 已登录用户

要把通知发到某人使用的每台设备,请把各设备关联到你自己的用户 ID。客户端 SDK 会带上 ?user_id=… 调用你的令牌端点;端点确认请求来自该已登录用户后,返回用密钥通过 generateToken 生成的令牌(每个 Beams 服务端 SDK 都有此方法)。之后即可推送给用户 ID,而不是兴趣。删除用户会解除其所有设备的关联。

用户退出登录时请调用 stop,避免同一台设备的下一位用户收到其通知。

5. 发送测试

在应用页面的“推送通知 › 发送测试”中输入兴趣(上面示例为 hello)、标题和正文,然后点击“发送测试”。订阅该兴趣的设备几秒内就会收到,订阅者仪表会显示已注册的设备和浏览器数量。

故障排查

设备或浏览器始终没有出现在订阅者中
确认客户端以此应用的实例 ID 和端点调用 start,并且用户已允许通知。在 Android 上,google-services.json 必须与你上传的服务账号来自同一个 Firebase 项目。
iPhone 和 iPad 收不到通知
APNs 环境必须与构建一致:从 Xcode 运行的构建用“开发环境(沙盒)”,TestFlight 和 App Store 用“生产环境”。Bundle ID 必须与 App 完全一致,且 App Target 需开启 Push Notifications 能力。
start() 失败并提示“service worker missing”
/service-worker.js 必须放在网站根目录、通过 HTTPS 提供,并包含 Web 指南中的 importScripts 那一行。放在子目录中的 Service Worker 只能控制该目录。
iPhone 上的 Safari 从不请求通知权限
iOS 和 iPadOS 16.4 及以上的 Web Push,必须先把网站添加到主屏幕才能使用,且权限提示必须由点按触发。
服务端 SDK 仍然连接 pusher.com,或改走 http 而失败
请设置 endpoint 选项。Node.js SDK 还需要 beams.protocol = 'https',Go SDK 则使用 WithCustomBaseURL。
推送返回 401
服务器用错了密钥,或用的是已轮换且超过宽限期的旧密钥。请从应用页面复制当前密钥。
推送返回 429
推送速度超过了套餐上限。请等待 Retry-After 指定的时间,并在一次推送中指定最多 100 个兴趣或 1,000 个用户,而不是每个各发一次请求。
注册设备返回 402
应用已达到套餐的订阅者上限。请升级套餐,或删除已离开的用户以移除他们的设备。
setUserId 失败
你的令牌端点必须针对被询问的 user_id,用此应用的密钥调用 generateToken,并以 200 返回其 JSON。已关联其他用户的设备必须先调用 stop。

要从 Pusher Beams 迁移?把客户端 SDK 包换成我们的、在服务端 SDK 中设置端点、上传 APNs 密钥和 FCM 服务账号,并在用户更新 App 之前同时向两边推送。设备会在首次启动时重新注册。 从 Pusher 迁移 →