Push notifications

Every app is an installable PWA, and every notify a workflow sends also goes out as a push notification (Firebase Cloud Messaging) to the recipient's devices that turned notifications on. app.push is the per-device switch.

1 membersSDK referenceGuide: Run work in the background

On this page
  1. app.push
  2. app.push

Signed-in users are offered "Turn on notifications" once by the app itself; build your own settings toggle with app.push. Who gets what is decided on the server by ctx.notify (one account, one role or everyone); a tapped notification opens the notify action's link.

Push runs through the platform's Firebase project unless the app sets its own FIREBASE_SERVICE_ACCOUNT and FIREBASE_WEB_CONFIG secrets. On iPhone and iPad, web push needs the app added to the Home Screen first.

app.push

app.pushproperty

Push notifications on this device for the signed-in account. status() says where things stand; enable() shows the browser's permission prompt and subscribes the device (call it from a click); disable() stops them here; test() sends a test push to your own devices.

app.push: AppPush
Returns
AppPush: status(), enable() and disable() resolve to "unsupported" (this browser can't: http:, an in-app browser, iOS outside a Home Screen app), "unavailable" (push isn't set up for the app), "prompt", "denied" (blocked in the browser's site settings) or "on". test() resolves { sent }.
Errors
  • test() rejects with "push notifications aren't available in this preview" without a runtime, SIGN_IN_REQUIRED, PUSH_OFF or RATE_LIMITED (one test every 10 seconds).
  • enable() rejects with the server's message if the device can't be saved (SIGN_IN_REQUIRED, PUSH_STORE_FAILED).
Permissions
A browser can only register, remove or test its own device for the signed-in account. Sending to anyone else happens only server-side, through ctx.notify. Signing out removes the device.
Example
const [state, setState] = useState<string>("prompt");
useEffect(() => { void app.push.status().then(setState); }, [app]);
return state === "on"
  ? <Button onClick={async () => setState(await app.push.disable())}>Turn off notifications</Button>
  : <Button disabled={state !== "prompt"} onClick={async () => setState(await app.push.enable())}>Turn on notifications</Button>;

Source: packages/appkit/src/kits/primitives/app-handle.ts:249