← 所有指南

推播通知

推播通知整合指南

透過 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 遷移 →