ФАЗА 41. МОБИЛЬНАЯ WEB-FIRST Push

Web Push и нативный push идут разными путями

FCM · APNs · Tokens

Браузерная подписка и нативный токен требуют разрешения, регистрации на backend и обработки доставки на конкретной ОС.

1. Push начинается с разрешения пользователя

1 / 5

Приложение объясняет пользу и запрашивает доступ, затем получает браузерную подписку или нативный токен.

  • Отказ сохраняет рабочий сценарий.
  • Запрос идёт в контексте.
  • Токен не является постоянным.
РазрешениеПодписка или токенРегистрация backend

2. Web Push проходит через push service браузера

2 / 5

Service worker получает событие push от браузерного сервиса и показывает уведомление даже без открытой страницы в поддерживаемом сценарии.

  • VAPID идентифицирует отправителя.
  • Payload защищён.
  • Click открывает нужный URL.
BackendBrowser push serviceService worker

3. FCM и APNs доставляют нативные сообщения

3 / 5

Backend отправляет через FCM для Android и APNs для iOS, ОС решает отображение с учётом режима и разрешений.

  • Токен принадлежит устройству и app.
  • Сервер хранит учётные данные.
  • Истёкший токен удаляется.
BackendFCMAPNsУстройство

4. Capacitor связывает события с JS

4 / 5

Плагин регистрирует токен, передаёт его backend и вызывает обработчики получения и открытия уведомления.

  • Обработчики регистрируются заранее.
  • Cold start имеет initial notification.
  • Дедупликация предотвращает повтор действия.
Native eventCapacitor listenerОбработка в приложении

5. iOS проверяется отдельно

5 / 5

Web Push доступен не во всех режимах, нативный APNs требует правильного профиля и entitlement, тихие уведомления ограничены.

  • Установка влияет на возможности.
  • Production и sandbox различаются.
  • Реальное устройство обязательно.
Web Push на iOSНативный APNs

Push-уведомления в мобильном вебе

← назад к разделу

Пользователь закрыл приложение — и связь с ним оборвалась. Push-уведомления решают эту задачу: позволяют отправить сообщение на устройство, даже когда приложение не открыто. Но в мобильном вебе существует два совершенно разных пути доставки push, и они работают по-разному на разных платформах.

Два пути: web push и нативный push

Раньше уведомления были доступны только нативным приложениям — нужно было публиковать приложение в магазине и использовать системные API. Браузеры этого не умели.

Со временем появился Web Push — стандартный браузерный механизм. Он строится на трёх составляющих:

  • Push API — браузер подписывается на уведомления и получает уникальный endpoint.
  • Notification API — показывает уведомление на экране.
  • Service worker — принимает входящее сообщение и показывает уведомление, даже когда вкладка закрыта.

Схема работает так: бэкенд отправляет зашифрованное сообщение на endpoint пользователя, push-сервис браузера (у Google — FCM, у Apple — APNs) доставляет его, service worker просыпается и показывает уведомление.

Нативный push работает иначе: приложение в нативной обёртке регистрируется напрямую в платформенной службе доставки, получает device token и отдаёт его бэкенду. Дальше сервер отправляет сообщение через платформенный шлюз — минуя браузер.

Главное отличие:

Web PushНативный push
Нужна обёртка?НетДа (Capacitor / магазин)
Работает на AndroidДаДа
Работает на iOSТолько установленное PWA (16.4+)Да, надёжно
НастройкаТолько бэкендПлатформенная (FCM, APNs, сертификаты)

FCM и APNs — что это такое

Нативную доставку обеспечивают две разные службы.

FCM (Firebase Cloud Messaging) — сервис Google. Бэкенд отправляет сообщение в FCM, тот доставляет его на Android-устройство.

APNs (Apple Push Notification service) — сервис Apple. Без него push на iPhone не придёт — никаким другим способом уведомление на iOS не доставить.

На практике используют такую схему: FCM выступает единым шлюзом и для iOS тоже. APNs-ключ загружается в Firebase, бэкенд работает только с FCM, а FCM сам ретранслирует сообщения в APNs. Это убирает из бэкенда вторую интеграцию.

Что потребуется настроить:

  • Android — файл google-services.json в проекте.
  • iOS — платный аккаунт Apple Developer, APNs-ключ (.p8), включённая capability «Push Notifications» в Xcode.

Подключение через Capacitor

В приложении на Capacitor нативный push подключается плагином @capacitor/push-notifications. Он даёт единый API поверх FCM и APNs: запрос разрешения, регистрация, получение токена и обработка событий.

npm install @capacitor/push-notifications
npx cap sync
import { PushNotifications } from "@capacitor/push-notifications";

export async function registerPush(onToken: (token: string) => void) {
  let status = await PushNotifications.checkPermissions();
  if (status.receive === "prompt") {
    status = await PushNotifications.requestPermissions();
  }
  if (status.receive !== "granted") {
    throw new Error("push permission denied");
  }

  await PushNotifications.addListener("registration", (token) => {
    onToken(token.value); // отправить токен на бэкенд
  });
  await PushNotifications.addListener("registrationError", (err) => {
    console.error("push registration failed", err.error);
  });

  await PushNotifications.register();
}

Несколько важных моментов:

  • register() не показывает диалог — он только запускает регистрацию в FCM или APNs. Диалог разрешения вызывается отдельно через requestPermissions().
  • Токен приходит асинхронно в слушателе события registration, а не как возвращаемое значение.
  • Возможные значения status.receive: prompt, prompt-with-rationale (Android), granted, denied.
requestPermissions: системный диалог granted register: регистрация в FCM или APNs асинхронно событие registration: device token обновлять при каждом запуске токен на бэкенд, привязан к пользователю

Разрешение и токен это два отдельных шага; токен приходит событием, а не возвращаемым значением, и может смениться.

Разрешения и токены

Когда регистрация прошла успешно, device token нужно сохранить на бэкенде, привязав к пользователю. Именно по нему сервер потом адресует push конкретному устройству.

Токен не вечен — платформа может его сменить при переустановке, восстановлении из резервной копии или ротации ключей. Поэтому событие registration обрабатывают при каждом запуске приложения и обновляют токен на сервере.

// Push пришёл, пока приложение открыто
await PushNotifications.addListener("pushNotificationReceived", (notification) => {
  console.log("received", notification.title, notification.body);
});

// Пользователь тапнул по уведомлению
await PushNotifications.addListener("pushNotificationActionPerformed", (action) => {
  navigateTo(action.notification.data?.route);
});

Через поле data удобно передавать маршрут, чтобы открыть нужный экран при тапе.

Ограничения iOS

iOS — главная причина, по которой выбор пути не очевиден.

Web Push на iOS появился в версии 16.4, но с серьёзным условием: сайт должен быть установлен как PWA через «Поделиться → На экран Домой». Только тогда Push API и service worker становятся доступны. В обычной вкладке Safari web push на iPhone не работает вовсе. Плюс системный диалог разрешения можно показать только в ответ на явный жест пользователя — нельзя вызвать его автоматически при загрузке страницы.

Это и есть ключевая развилка. Если охват iOS критичен и нельзя рассчитывать, что пользователь установит PWA, надёжный путь один — нативный push через APNs в Capacitor-обёртке.

На Android и компьютерах таких ограничений нет — там web push работает в полную силу.

Коротко

  • Push-уведомления доставляются двумя путями: web push (браузерный стандарт) и нативный push (через FCM и APNs в Capacitor-обёртке).
  • Web push работает в PWA и браузере на Android и компьютерах без какой-либо нативной упаковки.
  • На iOS web push доступен только в установленном PWA (версия 16.4+) — в обычной вкладке Safari он не работает.
  • FCM (Google) и APNs (Apple) — платформенные службы доставки; FCM можно использовать как единый шлюз и для Android, и для iOS.
  • Плагин @capacitor/push-notifications даёт единый API поверх FCM и APNs.
  • Device token нужно обновлять на сервере при каждом запуске — он может измениться.
  • Для надёжного охвата iOS нужна Capacitor-обёртка и нативный push через APNs.

Что почитать дальше