КейсыРастИИшка
Разработка

Push-уведомления в приложении: сообщение должно дожить до смысла

Представим приложение доставки: в 19:10 оно сообщает, что курьер будет через пять минут. В 19:40 телефон выходит из режима без сети и показывает это же бодрое обещание. Курьер уже уехал, ужин остыл, уведомление всё ещё смотрит в будущее. Технически сообщение добралось. По смыслу — опоздало на собственные похороны.

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

Телефон получает актуальное напоминание, пока просроченные сообщения останавливаются на временной границе
Редакционная иллюстрация к теме статьи; не фотография клиентского проекта.

У сообщения есть срок годности, даже если маркетинг его не указал

Приглашение на встречу, изменение статуса заказа и предложение скидки живут разное время. Если приложение хранит их в одной очереди по одинаковым правилам, оно рано или поздно принесёт человеку новости из прошлого. Чем точнее действие привязано к моменту, тем важнее определить границу актуальности до отправки.

Для каждого типа события записывают: что случилось, кому это важно, какое действие ожидается и до какого времени оно полезно. «Курьер подъезжает» имеет короткий горизонт. «Отчёт готов» может оставаться полезным дольше. «Появилось новое сообщение» зависит от того, не прочитал ли человек его уже на другом устройстве. Одной универсальной настройки недостаточно.

Проверка актуальности нужна не только в очереди доставки. После нажатия приложение заново запрашивает состояние объекта: заказ уже отменён, встреча перенесена, сообщение прочитано. Уведомление становится приглашением посмотреть актуальное состояние, а не самостоятельным источником вечной истины. Старый текст нельзя механически использовать для выполнения необратимого действия.

Полезный вопрос к постановщику задачи: что будет, если человек увидит это через час, сутки или неделю? Если ответ вызывает неловкость, техническое задание ещё не закончено. Срок годности — часть содержания сообщения, а не тонкость серверной команды.

TTL ограничивает ожидание доставки, а не гарантирует момент показа

TTL — допустимое время жизни сообщения в механизме доставки. В документации Firebase Cloud Messaging о сроке жизни описаны параметры для разных платформ. Это способ ограничить хранение недоставленного сообщения, а не обещание показать его в заданную секунду. Сеть, состояние устройства и политика операционной системы остаются отдельными условиями.

Если срок актуальности события закончится через десять минут, на сервере вычисляют оставшееся время до этой границы. Повторная отправка через восемь минут не должна автоматически подарить сообщению ещё десять минут жизни. Иначе каждая попытка доставки продлевает вчерашнюю новость. Нужна абсолютная бизнес-граница, из которой рассчитывается допустимое ожидание конкретной попытки.

Нулевой или очень короткий срок подходит не каждому сценарию: сообщение может быть отброшено, если немедленная доставка невозможна. Длинный срок повышает шанс позднего появления, но не делает его полезным. Выбор — продуктовый компромисс. Для напоминания о скором действии пропуск иногда лучше запоздалого сигнала; для важного доступного документа позднее сообщение может быть уместным.

Внутри приложения должна оставаться история или актуальный экран, если без сообщения пользователь потеряет информацию. Push не стоит делать единственной копией критического события. Канал привлечения внимания по природе зависит от внешних условий, а состояние заказа или договорённости должно жить в системе независимо от того, разрешён ли звук на телефоне.

Срок жизни сообщения выводится из времени, когда действие ещё полезно; повтор не продлевает бизнес-событие.
Срок жизни сообщения выводится из времени, когда действие ещё полезно; повтор не продлевает бизнес-событие.

Смена статуса и цепочка событий требуют разного поведения

За десять минут заказ может пройти статусы «принят», «собран», «передан курьеру». Если телефон был без сети, человеку часто полезнее увидеть последнее состояние, чем три сообщения подряд. Но три новых входящих обращения от разных людей нельзя бездумно заменить одним последним текстом. Различие проходит между актуальным состоянием и самостоятельными событиями.

Механизмы свёртывания помогают заменять ожидающие сообщения одного класса. В документации FCM о collapsible-сообщениях приведены правила и ограничения платформ. Их нельзя трактовать как универсальное удаление всех старых уведомлений с экрана: замена ожидающего сообщения и уже показанная карточка — разные участки системы.

СценарийЧто важно сохранитьРазумная стратегия
Текущий статус одного заказаПоследнее подтверждённое состояниеЗаменять устаревшие ожидающие обновления по правилам платформы
Несколько независимых сообщенийСведения о каждом обращенииХранить события в системе, уведомлять группой или счётчиком
Кратковременное приглашениеВозможность успеть выполнить действиеОграничить срок и не показывать устаревший призыв

Ключ группировки выбирается по смыслу: тип состояния и объект, для которого допустима замена. Если все сообщения получают один общий ключ, они могут вытеснять друг друга там, где пользователь ждал разные новости. Если каждое получает случайный уникальный ключ, замена не произойдёт вообще. Название параметра короткое, цена ошибки вполне человеческая.

Для нескольких каналов сохраняют единый идентификатор события и версию состояния. Пользователь не должен получать «заказ отменён», а затем «заказ собирается» из запоздавшей резервной попытки. Доставка может нарушать ожидаемый порядок, поэтому клиент и сервер проверяют актуальность по данным системы, а не по порядку появления карточек на телефоне.

Высокий приоритет не превращает рекламу в важное событие

Разработчик может управлять доступными параметрами приоритета, но операционная система всё равно применяет свои ограничения. Если команда повышает приоритет всем рассылкам, это не гарантирует вечную заметность. Настройка должна соответствовать реальной срочности и техническим правилам платформы, а не желанию, чтобы пользователь немедленно оценил новый баннер.

Категории сообщений разделяют заранее: операционные изменения, напоминания, социальные события, обучающие подсказки, коммерческие предложения. Для каждой определяют частоту, тихие часы, допустимый звук и возможность отключения. Не нужно смешивать уведомление о безопасности и скидку в одну категорию, чтобы второе случайно воспользовалось важностью первого.

Срочность должна вытекать из действия: если человек ничего не теряет, увидев сообщение позже, ночное прерывание трудно оправдать. Для многих сценариев достаточно внутреннего центра уведомлений или следующего открытия приложения. Решение не отправлять push иногда является качественной продуктовой работой, хотя в отчёте рассылок оно выглядит подозрительно скромно.

Для Apple правила взаимодействия и разрешений описаны в документации User Notifications. Конкретные режимы доступности и поведения проверяют на поддерживаемых версиях устройств. В спецификации не следует обещать обход пользовательских настроек фокуса или гарантированный звук: внимание остаётся у владельца телефона.

Разрешение просят после объяснения пользы

Первое открытие приложения часто сопровождается парадом запросов: уведомления, геолокация, камера. Человек ещё не понял продукт, но уже должен раздать ему права. Более разумный момент связан с действием: пользователь подписался на изменение статуса, создал напоминание, ожидает ответ специалиста. Тогда просьба о разрешении имеет конкретный смысл.

Предварительный экран не должен маскировать системный диалог или обещать обязательность там, где функция необязательна. Нужно объяснить, какие сообщения появятся и как ими управлять. Отказ не повод блокировать весь продукт, если основные функции могут работать без push. Настройки и альтернативный способ увидеть событие помогают сохранить полезность приложения.

Для веб-сценариев MDN описывает разрешения Notifications API и требования среды выполнения. Разрешение на показ уведомлений не равно подписке на любую рекламную рассылку и не делает доставку безусловной. Техническое согласие браузера и применимые требования к коммуникациям рассматриваются отдельно.

Важно различать пользователей без запроса разрешения, отказавших, разрешивших и позднее изменивших настройки. Одна общая группа «не получают» ничего не объясняет. Интерфейс должен честно показывать текущее положение и не повторять раздражающую просьбу при каждом экране. Разрешение не вырастает от настойчивого полива.

Перед отправкой проверяют не только токен устройства, но и согласия, состояние и частоту.
Перед отправкой проверяют не только токен устройства, но и согласия, состояние и частоту.

Один человек в разные моменты — разные получатели

Сегментации «все пользователи приложения» недостаточно. Человек мог уже купить товар, закрыть задачу на компьютере, сменить регион или отказаться от категории сообщений. Перед отправкой полезно проверять свежие условия, которые делают событие уместным. Особенно если между постановкой в очередь и фактической отправкой прошло заметное время.

Условие должно быть воспроизводимым: отправляем напоминание только для незавершённой записи, которая начинается позже текущего времени и не отменена. Формулировка «активным клиентам» слишком размыта. Она не объясняет, почему конкретный человек получил конкретное сообщение. Продуктовый владелец обязан суметь восстановить это решение без гадания по рекламной кампании.

Проверяют также частоту на уровне человека, а не одного устройства. Если у пользователя телефон и планшет, два независимых планировщика могут удвоить шум. Для некоторых событий показ на каждом устройстве допустим, для других достаточно общего ограничения. Это определяется сценарием; универсальный запрет тоже способен помешать нужному оповещению.

Отдельное правило нужно для перехода между часовыми поясами. Время встречи хранится с корректным контекстом, тихие часы интерпретируются согласованно, а локаль влияет на текст. Сообщение «сегодня в девять» без ясного времени превращает экономию символов в задачу по астрономии. Короткий текст не должен требовать длинного расследования.

Экран блокировки — публичнее, чем кажется автору сообщения

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

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

При открытии уведомления приложение проверяет действующую сессию и права на объект. Если человек вышел из аккаунта или переключился на другой, старый push не должен показать чужие данные. Идентификатор события помогает найти запись, но не является разрешением её читать. Это особенно важно для приложений с несколькими организациями и семейными устройствами.

Логи доставки тоже требуют аккуратности. Для диагностики полезны идентификатор события, категория, время и результат обработки, но необязательно копировать весь персональный текст в аналитический сервис. Наблюдаемость должна объяснять маршрут сообщения без превращения журнала в новый незащищённый архив клиентских данных.

Повторная попытка не должна превращаться в повторное беспокойство

Сервер отправил сообщение, но не получил ответ из-за сетевого сбоя. Повторить безопасно или появятся две одинаковые карточки? Это задача идентификации событий и обработки повторов. Один бизнес-факт должен иметь устойчивый идентификатор, который сохраняется при технической повторной попытке. Новый случайный номер на каждом повторе скрывает дубликат от собственной системы.

При этом одинаковый текст не означает одинаковое событие. Два разных заказа могут одновременно получить статус «готов». Удалять один по совпадению строки нельзя. Правило устранения дублей опирается на объект, тип события и его версию. Для реального повторного события создаётся новая запись, даже если текст остался прежним.

Гонки возникают и после чтения. Человек уже открыл сообщение в приложении, но запланированный push ещё ждёт отправки. Перед фактической отправкой полезно проверить состояние, если это допустимо по нагрузке и сценарию. Полностью устранить все гонки во внешних системах сложно, поэтому текст и экран открытия должны корректно переживать позднее получение.

Нельзя обещать «ровно один показ» только на основании ответа API отправителя. Между приложением, провайдером, устройством и интерфейсом пользователя несколько независимых границ. Приёмка должна описывать наблюдаемое поведение и способы смягчения повторов, а также честные ограничения. Бесконечная уверенность обычно появляется там, где ещё не проверяли плохую сеть.

Идентификатор события сохраняется при повторе; приложение проверяет актуальное состояние после открытия.
Идентификатор события сохраняется при повторе; приложение проверяет актуальное состояние после открытия.

Успешная отправка — самая ранняя ступень, а не финиш

Воронку сообщений полезно разделить: событие создано, адресат выбран, условия отправки подтверждены, запрос принят провайдером, появились доступные признаки доставки, пользователь открыл, целевое действие выполнено. Не все платформы предоставляют одинаковые данные по каждому этапу. Отсутствующую метрику отмечают как недоступную, а не записывают в неё сто процентов.

Разные знаменатели отвечают на разные вопросы. Доля открытий среди отправленных показывает одно, среди разрешивших уведомления — другое, среди доступных признаков доставки — третье. В отчёте обязательно указывают определение. Смена знаменателя может улучшить красивую диаграмму, не изменив ни одного поведения пользователя.

Дополнительно оценивают отказ от категории, отключение разрешений, удаление приложения и обращения с жалобами, если соответствующие сигналы доступны и корректно интерпретируются. Рост открытий после агрессивной формулировки не гарантирует долгосрочную пользу. Человек способен открыть сообщение, чтобы понять, почему его снова потревожили.

Цель привязывают к типу уведомления. Для напоминания о записи важнее своевременное подтверждение или перенос, для отчёта — просмотр готового документа, для обновления заказа — снижение неопределённости. Не каждую операционную коммуникацию нужно оценивать дополнительной покупкой. Иногда хороший результат — человеку стало понятно, что происходит, и он не вынужден звонить в поддержку.

Десять тысяч отправок не равны десяти тысячам возможностей

Возьмём условный сервис записи. За неделю запланировано 10 000 напоминаний. Перед отправкой 800 записей отменены, 1 200 уже подтверждены по другому каналу, 500 относятся к пользователям, отключившим категорию. После исключения пересечений по конкретным пользователям и событиям остаётся 7 500 подходящих напоминаний. В примере группы не пересекаются; в реальном расчёте простое вычитание без проверки даст ошибку.

Допустим, в контролируемом учебном сравнении новая схема помогла дополнительно подтвердить 150 записей. Это ещё не 150 дополнительных посещений. Часть подтверждённых клиентов может не прийти, а часть неподтвердивших пришла бы и без сообщения. Для денежного вывода нужно сравнить фактические посещения или другую согласованную цель между сопоставимыми группами.

ИзмерениеУчебное значениеЧего оно не доказывает
Подходящие напоминания7 500Что все они доставлены и замечены
Дополнительные подтверждения150Что состоялось столько же дополнительных посещений
Завершённое целевое действиеНужно измерить отдельноЧто наблюдаемая разница вызвана только уведомлением

Все числа в примере учебные. Он нужен, чтобы остановить распространённый скачок от объёма рассылки к выручке. Стоимость инфраструктуры, разработки, поддержки и возможного раздражения пользователей входит в решение о масштабе. Если редкое важное сообщение полезно, это не означает, что полезны ещё семь рекламных сообщений между ним и пользователем.

Проверять нужно телефон, который живёт обычной жизнью

Тест на открытом приложении с идеальным Wi-Fi показывает только один благоприятный сценарий. Нужны выключенная сеть, длительный офлайн, заблокированный экран, закрытое приложение, ограниченная фоновая работа, смена аккаунта, разные разрешения и восстановление после обновления. Набор зависит от поддерживаемых платформ, но плохая связь обязана в нём присутствовать.

Проверяют задержку через границу актуальности: сообщение отправлено до окончания события, устройство появляется в сети после. Ожидаемое поведение фиксируют заранее. Затем тестируют несколько состояний одного объекта, независимые события с одинаковым текстом и повторную попытку после неопределённого сетевого ответа. Так обнаруживается большинство неприятных дублей и новостей из прошлого.

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

В протоколе испытаний сохраняют платформу, версию приложения, условия сети, разрешения, время события и наблюдаемый результат. Скриншот полезен, но без времени и условий не объясняет дефект. Один телефон разработчика не представляет всю аудиторию. Объём матрицы выбирают по риску и доле поддерживаемых устройств, а не по количеству свободных зарядок.

Хорошее ТЗ начинается со смысла события и заканчивается отказом от лишнего

Для одного типа уведомления можно составить короткий паспорт. В нём есть владелец, событие-источник, получатель, проверяемые условия уместности, абсолютная граница актуальности, правила повторов, категория разрешения, текст без лишних данных и целевое действие. Рядом — способ измерения и поведение при недоставке. После такого описания параметры API становятся следствием решения.

  1. Назвать действие, которое сообщение помогает выполнить вовремя.
  2. Определить, когда информация перестаёт быть полезной.
  3. Разделить заменяемые состояния и самостоятельные события.
  4. Проверять согласия и актуальность перед отправкой.
  5. Сохранить событие в приложении независимо от внешнего канала.
  6. Проверять права и состояние объекта после открытия.
  7. Измерять завершённое действие и нежелательные последствия отдельно от отправок.
  8. Испытать задержку, повторы, смену аккаунта и несколько устройств.

Такой механизм относится к проектированию приложений и разработке систем под бизнес-процесс. Добавление ИИ для текста не исправляет срок жизни события и разрешения. Генерация может помогать с вариантами формулировок, но правила актуальности и безопасности должны быть явными, проверяемыми и понятными владельцу продукта.

Начинать стоит с одного сообщения, после которого пользователь действительно успевает сделать полезное действие. Если команда не может назвать это действие и момент, когда оно уже поздно, отправку лучше отложить. Телефон умеет доставлять текст. Смысл до него должна довезти команда.

Частые вопросы

Что означает TTL у push-уведомления?

Это допустимое время жизни сообщения в механизме доставки. Оно ограничивает ожидание, но не гарантирует показ в конкретную секунду; параметры и поведение зависят от платформы.

Нужно ли показывать каждый промежуточный статус заказа?

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

Отправлено провайдеру означает доставлено пользователю?

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

Можно ли показывать персональные детали на экране блокировки?

Нужно учитывать чувствительность сведений и применимые требования. Безопаснее передавать нейтральное уведомление, а подробности показывать после входа и проверки доступа.

Как избежать устаревшего действия после открытия push?

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

Начать приложение с одной операции

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

Посмотреть форматы приложений ↗

Разобрать свой сценарий ↗

Сравниваете несколько направлений? Соберите бриф по задаче.