Push-устройства¶
Чтобы получать готовность генерации, когда приложение в фоне или закрыто, зарегистрируй push-токен устройства (FCM на Android, APNs на iOS). Тогда не нужно держать открытым SSE-стрим — система доставит уведомление.
Зарегистрировать токен¶
curl -X POST "$BASE_URL/v1/devices" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"token":"<fcm_or_apns_token>","platform":"fcm","device_id":"<id установки>"}'
# 204
platform—fcm(Android) илиapns(iOS); это просто метка ОС.token— FCM registration token из Firebase SDK на обеих платформах. На iOS это тоже FCM-токен (а не сырой APNs device token): доставка всегда идёт через FCM, а он сам отдаёт пуш в APNs.device_id— тот же идентификатор установки, что уходит при входе. Поле необязательное, но без него токен не защищён: с ним токен переходит на другой аккаунт только с той же установки, а запрос с чужимdevice_idполучает403(forbidden).- Повторная регистрация того же токена идемпотентна — можно слать при каждом старте.
Отвязать токен¶
Когда отвязывать
Отвязывай токен при выходе из аккаунта и при отзыве push-разрешения — иначе на
устройство будут приходить уведомления от чужой сессии. Сам push-токен также стоит
обновлять в сервисе, когда платформа его ротирует (callback onNewToken / APNs delegate).
Что бэкенд чистит сам
DELETE нужен не всегда — часть случаев сервис закрывает без участия клиента:
- Мёртвые токены (приложение удалено, токен протух). При первой же отправке
FCM ответит «токен невалиден» (
404/UNREGISTEREDилиINVALID_ARGUMENT), и строка удаляется автоматически — таблица самоподчищается. - Смена аккаунта на устройстве. Повторная регистрация того же токена под другим
пользователем с той же установки (тот же
device_id) переназначает его на нового владельца (rebind), старая привязка исчезает.
А вот logout и отзыв push-разрешения сервер сам не распознаёт: токен у
провайдера остаётся валидным, ошибки доставки нет, переназначения нет. Поэтому в этих
двух случаях явный DELETE обязателен — иначе токен зависнет на старом аккаунте до
следующей неудачной отправки.
Что приходит в push¶
Один канал, два повода. Различай по ключу в data — он же говорит, какой экран открыть.
Готовность генерации:
status — succeeded или failed; по тапу — экран генерации.
Решение по заявке на свой эффект (см. Свои эффекты):
status — approved, rejected или archived; по тапу — экран заявки.
Новости по уже опубликованному эффекту — приходят автору и не меняют статус заявки:
milestone — first_generation (кто-то впервые сделал генерацию этим эффектом),
earned (начислены кредиты за чужую генерацию), promoted (эффект перенесён из
«От сообщества» в тематическую категорию). По тапу — экран этого эффекта в кабинете
автора. Ключ здесь effect_id, а не submission_id: речь об эффекте, который уже
живёт в каталоге.
Push только будит клиент — данные всегда забираются обычным GET: результат генерации
из GET /v1/generations/{id} (result_url короткоживущий и в payload не кладётся),
детали заявки — из GET /v1/user-effects/{id}.
Пока экран открыт, push не нужен — обе сущности отдают SSE-стрим с тем же набором статусов.