Перейти к содержанию

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).
  • Повторная регистрация того же токена идемпотентна — можно слать при каждом старте.

Отвязать токен

curl -X DELETE "$BASE_URL/v1/devices/<token>" -H "Authorization: Bearer $TOKEN"
# 204

Когда отвязывать

Отвязывай токен при выходе из аккаунта и при отзыве push-разрешения — иначе на устройство будут приходить уведомления от чужой сессии. Сам push-токен также стоит обновлять в сервисе, когда платформа его ротирует (callback onNewToken / APNs delegate).

Что бэкенд чистит сам

DELETE нужен не всегда — часть случаев сервис закрывает без участия клиента:

  • Мёртвые токены (приложение удалено, токен протух). При первой же отправке FCM ответит «токен невалиден» (404/UNREGISTERED или INVALID_ARGUMENT), и строка удаляется автоматически — таблица самоподчищается.
  • Смена аккаунта на устройстве. Повторная регистрация того же токена под другим пользователем с той же установки (тот же device_id) переназначает его на нового владельца (rebind), старая привязка исчезает.

А вот logout и отзыв push-разрешения сервер сам не распознаёт: токен у провайдера остаётся валидным, ошибки доставки нет, переназначения нет. Поэтому в этих двух случаях явный DELETE обязателен — иначе токен зависнет на старом аккаунте до следующей неудачной отправки.

Что приходит в push

Один канал, два повода. Различай по ключу в data — он же говорит, какой экран открыть.

Готовность генерации:

{ "generation_id": "…", "status": "succeeded" }

status — succeeded или failed; по тапу — экран генерации.

Решение по заявке на свой эффект (см. Свои эффекты):

{ "submission_id": "…", "status": "approved" }

status — approved, rejected или archived; по тапу — экран заявки.

Новости по уже опубликованному эффекту — приходят автору и не меняют статус заявки:

{ "effect_id": "…", "milestone": "first_generation" }

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-стрим с тем же набором статусов.