Push
Удалённые push-уведомления. Как и Geolocation, это сервисный плагин —
типизированная обёртка над зарегистрированным хостом сервисом "push" — но большая часть
механики живёт вне твоего приложения: хост владеет системным токеном, запросом разрешения и
регистрацией на бэкенде le.codes; le.codes ретранслирует твои отправки в APNs/FCM, так что
в схеме по умолчанию (приложение LeCodes) ты вообще не касаешься учётных данных Apple/Google.
Опционален по хосту — всегда проверяй Push.isSupported.
Обзор
if (Push.isSupported) {
const { address } = await Push.register({ user: 'u42' })
// отдай `address` своему бэкенду — или пропусти его вовсе и таргетируй по id `user`
}
Push.addEventListener('message', p => toast(p.title)) // пришло, пока приложение открытоДальше твой сервер (или curl) отправляет через реле:
POST https://le.codes/api/projects/<projectUuid>/push/send
Authorization: Bearer lecodes_pk_… ← a project push key le.codes minted for you (see below)
{ "title": "Order shipped", "users": ["u42"], "url": "myapp://orders/42" }API
Push.isSupported: boolean // зарегистрировал ли этот хост сервис?
Push.getStatus(): Promise<PushStatus> // никогда не показывает запрос разрешения
Push.register(options?: { user?: string }): Promise<{ address: string }>
Push.unregister(): Promise<void>
Push.getLaunch(): Promise<PushPayload | null>
Push.addEventListener('message' | 'tap', cb: (p: PushPayload) => void): void
Push.removeEventListener('message' | 'tap', cb): void
interface PushPayload {
title: string
body?: string
url?: string // deep link — также приходит через app.launchUrl / событие "url"
data?: Record<string, any> // твой JSON, ≤ 2 КБ в сериализованном виде
badge?: number
}
interface PushStatus {
permission: 'granted' | 'denied' | 'prompt'
registered: boolean
}- Системный запрос разрешения происходит внутри
register()— и никогда раньше.register()идемпотентен (безопасен на каждом запуске) и отклоняется с"denied"/"unavailable". На хостах без сервиса каждый метод отклоняется сразу, до любого пути с разрешением. - Когда приходит push, твоё приложение не запущено — уведомление показывает ОС. Приложение
видит ровно три пути доставки: событие
"message"(пришло, пока приложение было открыто — без баннера), событие"tap"(тапнули, пока приложение работало) иPush.getLaunch()(уведомление, холодным стартом запустившее этот сеанс). urlв полезной нагрузке — одновременно deep link: он доставляется и черезapp.launchUrl/ событие приложения"url", так что приложения с маршрутизацией по ссылкам получают маршрутизацию уведомлений, не трогаяPush.
Идентификация ТВОИХ пользователей
register({ user }) помечает устройство собственным id пользователя твоего приложения, а API
отправки принимает users: ["u42"] — один пользователь разворачивается во все его устройства,
и твой бэкенд никогда не хранит адреса. Повторная регистрация без user снимает метку (логаут).
id пользователя утверждается клиентом — любое устройство с твоим приложением может заявить любой id и заодно получать уведомления этого пользователя. Годится для «заказ отправлен»; никогда не таргетируй секреты по id пользователя.
Отправка
Во время разработки учётные данные не нужны вовсе — CLI отправляет от твоего логина:
lecodes pn devices # did the device actually register?
lecodes pn send --title "Order shipped" --user u42Для собственного сервера используй проектный push-ключ (lecodes_pk_…). le.codes его
генерирует — выбрать свой нельзя, и показывается он ровно один раз, так что сохрани его при
создании:
lecodes pn keys new "prod server" --env # writes LECODES_PUSH_KEY= into .envили настройки проекта → Push notifications → New key (только владелец; панель заодно даёт
готовый запрос). Ключ может отправлять push-уведомления ТОЛЬКО для своего проекта — намеренно
бесполезен для чего-либо ещё, в отличие от персонального токена доступа, поэтому деплоить нужно
именно его. Потерянные ключи не восстанавливаются: выпусти новый и отзови старый. Персональные
токены с доступом разработчика тоже работают на этом маршруте (именно их использует
lecodes pn send).
Таргетинг: to: [address…], users: [id…] или оба сразу — ответ { sent, failed: [{address, reason}] }. Неизвестные адреса отклоняют весь батч; пользователь без устройств — просто ноль
отправок.
push нужен атрибутированный мир — приложение LeCodes знает, какой проект оно запускает,
только когда это объявил доверенный лончер (запуски опубликованных проектов по QR / ссылке /
из онбординга). Бандлы lecodes dev не атрибутированы, поэтому Push.register() там
отклоняется с "unavailable" — тестируй push через опубликованный проект, открытый по QR.
Собственное приложение (standalone-оболочка)
Тот же бандл и тот же код работают в оболочке lecodes app: оболочка регистрирует тот же сервис
"push" со своим bundle id и твоим собственным ключом APNs (загруженным в настройки проекта),
а твой сервер шлёт точно такой же запрос — реле подбирает учётные данные по регистрации.
Смотрите также
- Geolocation — паттерн сервисного плагина, которому следует Push
- app —
app.launchUrl+ событие"url"(путь deep link) - Соглашения — гейтинг хоста