Блог · 02.09.2026

Push-уведомления не приходят: где искать причину

Жалоба «пуши не приходят» — одна из самых частых после запуска приложения. Неприятность в том, что почти все причины молчаливые: приложение работает, ошибок нет, сервер отвечает «отправлено», а на телефоне тишина. Ниже — порядок проверки, который мы прогоняем сами, от самого частого к редкому.

Сначала — доходит ли до устройства токен

Прежде чем что-то отправлять, приложение должно получить токен устройства и передать его на сервер. Половина случаев «не приходят пуши» заканчивается здесь: токен не получен или не сохранён.

Проверяется просто: посмотрите в базе, сколько записей пользователей имеет непустой токен. Если из сотни клиентов токен есть у нуля — отправлять некуда, и остальные проверки бессмысленны.

Две ловушки, на которые мы натыкались вживую. Первая: колонка под токен заведена как varchar(75), а токен FCM бывает длиной 140–190 символов — база молча обрезает его, и отправка уходит на несуществующий адрес. Вторая: эндпоинт сохранения токена объявлен публичным, идентификатор пользователя в него не передаётся, токен пишется «в никуда» и к аккаунту не привязывается.

iOS: есть ли ключ APNs в проекте

Для iPhone одного Firebase мало. В проекте Firebase должен лежать ключ APNs — тот самый .p8, который выпускается в аккаунте Apple Developer. Без него getToken() просто не возвращает токен, а в консоли не появляется ни одной ошибки.

Особенно легко это пропустить, когда несколько приложений живут в одном проекте Firebase: ключ забыли добавить один раз — пуши мертвы у всех приложений проекта сразу. Проверить можно за минуту: настройки проекта, вкладка Cloud Messaging, раздел конфигурации приложений Apple.

Второй нюанс — порядок вызовов. Токен FCM нужно запрашивать после того, как получен токен APNs, иначе на части устройств запрос вернёт пустоту. И третий: на симуляторе токен не выдаётся вообще, проверять пуши можно только на живом устройстве или через TestFlight.

Разрешение от пользователя

С iOS 12 и Android 13 уведомления требуют явного согласия. Если приложение спросило разрешение в неудачный момент — на первом же экране, до того как человек понял, зачем оно ему, — большинство нажимает «Не разрешать». Дальше система молча отбрасывает все уведомления, и никакая настройка сервера этого не изменит.

Хорошая практика: спрашивать разрешение в момент, когда польза очевидна. Оформил заказ — «сообщить, когда курьер выедет?». Записался на приём — «напомнить за час?». Конверсия согласий вырастает в разы против запроса на старте.

Сервер: что именно отправляется

Если токены есть и разрешение получено, проверяем саму отправку. Здесь встречается неочевидное: пустое поле data в сообщении FCM даёт ответ 400, а функция отправки нередко написана так, что молча возвращает «не отправлено» и никуда об этом не пишет.

Полезное правило: логировать каждую попытку отправки вместе с ответом сервиса. Тогда вопрос «почему не пришло» решается просмотром журнала, а не гаданием.

Проверка одной командой

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

Что делать по порядку

Смотрим базу: есть ли токены и не обрезаны ли они. Смотрим Firebase: лежит ли ключ APNs. Смотрим приложение: когда спрашивается разрешение и на живом ли устройстве проверяем. Смотрим сервер: пишется ли журнал отправок и что отвечает сервис. В девяти случаях из десяти причина находится на первых двух шагах.

Если разбираться некогда — напишите нам: мы делаем такую диагностику по чужому коду, обычно она занимает несколько часов и заканчивается конкретным списком правок.

Android: свои особенности

На Android к общим причинам добавляются фирменные оболочки. Xiaomi, Huawei, Oppo, Vivo и Samsung по-своему экономят батарею и умеют выгружать приложение из памяти вместе с его соединением для уведомлений. Приложение при этом установлено, разрешение выдано, но пуши приходят с задержкой в часы или не приходят вовсе.

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

Вторая особенность Android — каналы уведомлений. С Android 8 каждое уведомление относится к каналу, и настройки канала задаются один раз при создании. Если канал создан со звуком «без звука», поменять это позже из кода нельзя — только пересоздать канал с новым идентификатором. Мы видели приложения, где уведомления приходили молча именно из-за этого.

Тихие и видимые уведомления

Сообщение FCM бывает двух типов, и путаница между ними даёт странное поведение. Уведомление с полем notification система показывает сама, даже когда приложение закрыто, — но обработать его в коде вы не сможете, пока пользователь не нажмёт. Сообщение только с полем data приложение обрабатывает само, но если оно выгружено из памяти, показать уведомление некому.

Практический вывод: для обычных оповещений («заказ готов», «пришло сообщение») отправляйте notification — так надёжнее. Для фоновых задач вроде обновления данных — data. Смешивать оба поля в одном сообщении можно, но поведение на разных версиях систем отличается, и это источник трудноуловимых различий между iPhone и Android.

Что писать в уведомлении

Техническая часть — половина дела. Вторая половина в том, что человек может отключить уведомления вашего приложения одним движением, и вернуть его почти невозможно. Отключают за навязчивость: три сообщения в день про акции, уведомления ночью, текст без смысла вроде «У нас новости!».

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

Готовы обсудить?

Получите просчёт стоимости и сроков за 24 часа.

Подписываем NDA до получения детального ТЗ. Отправляем смету, презентацию команды и портфолио по теме вашего проекта.

+7 705 966 25 25 WhatsApp

Заявка

Звонок WhatsApp