Через какие сервисы проходит пуш-уведомление на iOS и Android?
Что проверяют
Понимаете ли вы, где искать причину, когда уведомление не пришло. Для тестировщика это вопрос про разграничение ответственности: цепочка длинная, и дефект может сидеть в бэкенде, в облаке платформы, в самом приложении или в настройках устройства.
Как отвечать
Схема на обеих платформах одинаковая: приложение регистрируется и получает токен, отдаёт его бэкенду, бэкенд обращается к облаку платформы, облако доставляет уведомление на устройство, системный слой показывает его пользователю.
На iOS посредник это APNs. Приложение сначала спрашивает разрешение у пользователя, потом получает токен устройства. Разрешение отзывается в настройках, а токен меняется при переустановке.
На Android посредник это FCM. Через него же часто ходят приложения, собранные одной библиотекой на обе платформы: в этом случае FCM для iOS сам передаёт уведомление дальше в APNs. На устройствах без сервисов Google работает свой сервис производителя.
Что из этого следует для проверок:
- доставка не гарантирована: облако вправе отбросить уведомление, если устройство долго офлайн;
- токен живёт своей жизнью: переустановка, очистка данных, восстановление из резервной копии дают новый токен, а старый становится невалидным, и бэкенд обязан его удалять;
- проверять надо три состояния приложения: открыто, свёрнуто, выгружено, поведение в них разное;
- отдельно тихие уведомления без показа, глубокие ссылки и поведение при выключенных разрешениях.
Где спотыкаются
Говорят, что бэкенд шлёт уведомление прямо на устройство. Прямого канала нет, и все ограничения по размеру и частоте задаёт именно облако платформы.
Второе: считают пуш надёжной доставкой и строят на нём сценарий, где событие обязано дойти. Это лучшая попытка, а не гарантия, поэтому важные вещи дублируются запросом при открытии приложения.
Третье: заводят дефект «пуш не пришёл» без данных. В отчёте нужны идентификатор отправки, токен, время, состояние приложения и ответ облака. Без этого дефект ходит по кругу между командами и закрывается как невоспроизводимый.