Ошибки токенов push-уведомлений, которые ломают повторное вовлечение
Ошибки токенов push-уведомлений могут мешать доставке оповещений пользователям, которые вышли из аккаунта, сменили учетную запись или используют второе устройство. Узнайте, какие проверки команды часто пропускают.

Почему эта проблема остается незаметной
Ошибки токенов push-уведомлений редко проявляются громко. Кампания уходит, провайдер принимает большую часть сообщений, а журнал отправки выглядит чисто. Команда видит «отправлено» или «принято» и думает, что пользователи увидели уведомление, хотя часть из них не получила ничего.
Этот разрыв долго вводит людей в заблуждение. Провайдеры push обычно говорят только о том, приняли ли они сообщение для токена, а не о том, увидел ли его человек. Если в вашей базе все еще лежат старые токены после переустановки приложения, смены телефона или устаревшего сеанса, цифры снаружи могут выглядеть нормально.
Ситуация ухудшается, потому что плохие токены часто портятся медленно. Один сломанный токен не рушит всю кампанию. И десять тоже. Урон растягивается на недели, а потом сливается с обычным падением открытий, удержания или повторных визитов. Продуктовая команда может увидеть небольшой спад и обвинить слабый текст, неудачное время или усталость аудитории, прежде чем кто-то проверит, работает ли еще поток обновления токена.
Выход из аккаунта делает проблему еще менее заметной. Если пользователь выходит, а потом другой человек входит на том же телефоне, старый токен может остаться привязанным к чужому аккаунту. Сообщения по-прежнему уходят из вашей системы. Они могут даже дойти до настоящего устройства. Просто они доходят не до того человека или перестают доходить до кого-либо после того, как приложение меняет токен, а backend так и не обновляет его.
Push-уведомления на нескольких устройствах скрывают ошибки еще одним способом. Пользователь может по-прежнему получать оповещения на один телефон, поэтому в поддержку никто не жалуется. Второй телефон молчит, потому что его токен истек или отвязался от аккаунта. С точки зрения пользователя уведомления кажутся ненадежными. С точки зрения команды все выглядит почти нормально.
Поэтому ошибки токенов push-уведомлений так долго живут. Они прячутся внутри приличных дашбордов, смешанного поведения пользователей и небольших потерь, которые накапливаются. Если состояние токена неверное, никакая смена текста или тест времени отправки не решит настоящую проблему.
Где ломаются данные токенов
Многие ошибки токенов push-уведомлений начинаются с ложного предположения: один телефон, один токен, один пользователь. Реальные устройства так аккуратно не работают. Токены меняются, пользователи переключают аккаунты, а старые записи остаются дольше, чем ожидает команда.
Переустановка приложения часто создает новый токен. Если backend хранит старый токен и никогда не заменяет его, следующая кампания может уйти на несуществующий адрес. В приложении все выглядит нормально, но повторное вовлечение падает, потому что вы все еще доверяете токену, который уже не относится к этой установке.
Операционная система тоже может обновить токен после апдейта, восстановления или изменений со стороны провайдера. Значит, токен — это не постоянный ID устройства. Относитесь к нему как к детали сеанса, которая может измениться в любой момент. Когда приложение получает новый токен, оно должно сразу отправить его в backend и пометить старый как устаревший.
Выход из аккаунта вызывает другой тип поломки. Устройство все еще существует, но связь между пользователем и устройством уже не должна оставаться. Если человек выходит из аккаунта, а backend сохраняет эту связь, позже вы можете отправить личные уведомления не тому человеку.
Особенно часто это всплывает на общих планшетах и тестовых телефонах, где люди входят и выходят из аккаунтов весь день.
Два аккаунта на одном устройстве создают еще один тихий сбой. Пользователь входит в аккаунт A, а потом в аккаунт B на том же телефоне. Если сервер хранит только одну строку на токен и бездумно переписывает user ID, можно потерять историю аккаунтов или оставить старые связи. Токен принадлежит установке приложения на этом устройстве, а не человеку навсегда.
Более безопасная модель проста. Храните токен, данные устройства, версию приложения, платформу, user ID и статус. Обновляйте эту запись каждый раз, когда приложение сообщает об изменении. Убирайте или отключайте привязку к пользователю при выходе из аккаунта. Оставляйте достаточно истории, чтобы видеть, когда одно устройство перешло от одного аккаунта к другому.
У большинства команд проблема не с отправкой. Проблема с сопоставлением. Когда изменения токена и смена аккаунта живут в одной таблице и подчиняются одним правилам, доставке становится гораздо проще доверять.
Как обрабатывать обновление токена шаг за шагом
Большинство ошибок токенов push-уведомлений начинается с небольшой задержки. Приложение получает новый токен, но слишком долго ждет, прежде чем отправить его, или отправляет его без достаточного контекста, чтобы аккуратно заменить старый.
Обновление должно идти одним и тем же путем каждый раз. Как только устройство получает новый токен, приложение должно немедленно отправить его в backend. Не откладывайте это на потом и не думайте, что старый токен еще будет работать пару дней. Именно в такой паузе начинает ломаться повторное вовлечение.
Храните по одной записи на каждое реальное устройство. Когда приходит новый токен, сохраняйте сам токен вместе с платформой, версией приложения и временем последнего появления. Эти дополнительные данные потом помогают поддержке ответить на простой вопрос: пользователь перестал получать уведомления потому, что вышел из аккаунта, сменил телефон или просто не открывал обновленное приложение?
Важно не только что записывать, но и как. Если у того же телефона уже есть запись устройства, заменяйте старый токен в этой записи вместо того, чтобы создавать еще одну строку и надеяться, что логика отправки выберет правильную. Команды часто оставляют оба токена, и тогда один пользователь случайно превращается в две или три цели.
Обновляйте привязку к аккаунту в той же самой записи. Если Мария входит в общий семейный планшет после Алекса, обновленный токен должен сразу начать относиться к аккаунту Марии. Если сначала обновить токен, а связь с аккаунтом позже, даже короткая задержка может отправить следующую кампанию не тому человеку.
Простой поток обновления выглядит так:
- Приложение получает новый токен.
- Оно одновременно отправляет токен, платформу, версию приложения, ID устройства и текущий user ID.
- Backend находит нужную запись устройства и заменяет старый токен.
- Backend обновляет привязку к аккаунту и время последней активности в той же операции.
- Система записывает событие обновления с достаточной детализацией для QA и поддержки.
Последняя запись в журнале экономит время. Когда кто-то говорит: «Я перестал получать уведомления после переустановки приложения», команда может проверить одну цепочку событий вместо догадок.
Правила для выхода из аккаунта и переключения между ними
Большинство проблем с уведомлениями после выхода из аккаунта начинается с одного неверного предположения: push-токен принадлежит пользователю. Это не так. Токен принадлежит установке приложения на конкретном устройстве, а backend лишь на какое-то время связывает это устройство с пользователем.
Когда пользователь выходит из аккаунта, разрывайте эту связь на сервере сразу. Не удаляйте запись устройства, если приложение не исчезло. Оставьте устройство, его токен, версию приложения и время последнего появления. Уберите только связь с аккаунтом, подписки на темы, завязанные на этого пользователя, и любые маркетинговые или продуктовые сегменты, которые зависят от личности.
Это разделение особенно важно, когда один телефон переходит из рук в руки. Семейный планшет, общий тестовый телефон или рабочее устройство могут переключаться между аккаунтами несколько раз за день. Если приложение хранит старый user ID в локальном хранилище, отложенные задачи могут отправить токен обратно вместе с устаревшими данными об идентичности. Это одна из самых частых ошибок токенов push-уведомлений, и она молчит, пока кто-то не получит чужие оповещения.
Безопасный сценарий выхода обычно прост:
- сообщить backend, что пользователь вышел из аккаунта
- отвязать токен устройства от этой учетной записи
- очистить локальные данные пользователя, кэш профиля и ожидающее состояние синхронизации
- оставить сырой токен устройства локально, чтобы приложение могло использовать его позже, если он все еще действителен
Следующий вход требует такой же аккуратности. Не привязывайте токен к новому аккаунту, пока вход еще выполняется. Подождите, пока авторизация завершится, приложение получит финальный user ID и будет завершена очистка после смены аккаунта. Затем отправьте один свежий запрос регистрации с текущим токеном, текущим пользователем и текущими данными устройства.
Небольшая гонка событий может создать большой хаос. Допустим, Анна выходит из аккаунта, а потом Бен входит на том же телефоне. Если приложение отправит запрос на вход Бена до того, как очистит локальное состояние Анны, backend может оставить связь токена Анны или создать две связи для одного устройства. Бен пропустит свои уведомления, а Анна получит его сообщения о доставке.
Команды, которые хорошо работают с push-уведомлениями на нескольких устройствах, воспринимают выход из аккаунта как изменение личности, а не просто смену экрана. Одна эта привычка предотвращает массу неверных отправок.
Мультиустройства без догадок
Пользователи редко остаются только на одном телефоне. Они переустанавливают приложение, добавляют планшет или держат рабочее устройство рядом с личным. Если ваша модель данных предполагает, что один пользователь равен одному токену, push-уведомления на нескольких устройствах ломаются тихо.
Один пользователь, один токен — это shortcut, из-за которого возникает большая часть проблем. У пользователя может быть много активных записей устройств, и у каждой установки приложения должна быть своя запись. Это значит, что один телефон с двумя установками может вести себя иначе, чем другой телефон в том же аккаунте.
Хорошая запись устройства обычно хранит:
- user ID, связанный с этой установкой
- стабильный ID установки или устройства
- текущий push-токен
- простую метку вроде «iPhone 15» или «Pixel 8 work»
- время последней проверки и активный статус
Эта метка помогает больше, чем ожидают команды. Когда кто-то говорит: «Мой старый планшет все еще получает уведомления», поддержка может проверить точную запись вместо того, чтобы гадать, какой токен относится к какому устройству.
Для старых записей нужен срок устаревания. Если устройство долго не появляется в системе, пометьте его как неактивное и уберите из рассылок. Если хотите, храните запись для истории, но не считайте молчание доказательством того, что устройство все еще должно входить в активный набор.
Логика отправки должна оставаться простой. Если только пользователь не настроил что-то отдельно на конкретном устройстве, отправляйте на все активные устройства в аккаунте. Большинство людей хотят получать уведомление там, где они сейчас вошли в систему. Если нужен только один девайс, сохраняйте это как реальное предпочтение, а не заставляйте систему доставки угадывать.
Для выхода из аккаунта тоже должно быть свое правило. Когда пользователь выходит, сразу деактивируйте эту установку для данного аккаунта. Если потом тот же телефон войдет в другой аккаунт, привяжите установку к новому аккаунту с ее текущим токеном. Многие ошибки токенов push-уведомлений начинаются тогда, когда команды повторно используют старую связь устройства и надеются, что следующий вход все исправит.
Такой подход требует чуть больше работы вначале. Зато потом он экономит очень много времени поддержки.
На какую обратную связь от провайдера реагировать
Провайдеры push говорят больше, чем просто «отправлено» или «ошибка». Если провайдер сообщает, что токен недействителен, истек или больше не зарегистрирован, воспринимайте это как изменение состояния в своих данных. Не оставляйте токен активным и не надейтесь, что следующая кампания сработает.
Одна эта привычка предотвращает множество ошибок токенов push-уведомлений. Команды часто логируют ошибку, идут дальше и еще днями или неделями держат тот же токен в очереди. Отчет по кампании выглядит загруженным, а повторное вовлечение тихо проседает.
Отклоненный токен должен сразу обновлять таблицу устройств. Пометьте устройство как неактивное, сохраните код ошибки провайдера и зафиксируйте время. Если пользователь позже откроет приложение и зарегистрирует свежий токен, вы сможете снова активировать это устройство на чистых данных, а не гадать.
Временные сбои требуют другого подхода. Таймаут, ограничение по скорости или сбой у провайдера не означает, что токен умер. Оставьте устройство активным, запишите ошибку и повторите попытку с задержкой. Если провайдер уже сказал, что токен исчез, больше не пытайтесь его отправлять. Повторные попытки только тратят деньги, искажают статистику доставки и скрывают настоящую проблему.
Простые правила помогают:
- Недействительный или незарегистрированный токен: сразу отключите эту запись устройства.
- Временная ошибка провайдера: оставьте запись активной и повторите позже.
- Неизвестная ошибка, которая повторяется: пометьте ее на проверку после нескольких попыток.
- Новый токен с того же устройства: замените старый токен и сохраните историю устройства.
- Резкий рост отклонений: проверьте недавние изменения в приложении, авторизации или backend в тот же день.
Записывайте каждое событие отказа обратно в таблицу устройств, а не только в журналы кампаний. Системе отправки нужна правда на уровне устройств. Маркетологу может быть важно, что 8 000 push не прошли. Приложению нужно знать, какой именно телефон перестал принимать сообщения и почему.
Резкие всплески важнее единичных ошибок. Если ошибки недействительного токена резко выросли сразу после релиза приложения, обновления SDK или изменения авторизации, вероятно, что-то сломало поток обновления токена. Если на прошлой неделе изменили логику выхода из аккаунта, а ответы «незарегистрирован» внезапно выросли, приложение, возможно, все еще отправляет старые токены после переключения аккаунтов.
Обратная связь от провайдера должна быстро менять поведение системы. Мертвые токены должны выходить из пула отправки. Временные сбои нужно перепроверять аккуратно. Повторяющиеся данные об отказах должны вести команду в тот участок кода, где обрабатываются обновление токена, вход, выход и обновления устройства. Так вы поймаете тихую потерю доставки до того, как следующая кампания промахнется мимо половины аудитории.
Простой пример с одним пользователем и двумя телефонами
Сара входит в систему на старом телефоне в понедельник. Тем же вечером она входит и на новом телефоне. Теперь в вашей системе один пользователь с двумя активными записями устройств, и это нормально.
Чистая схема проста. Каждая установка приложения получает свою строку, и каждая строка хранит текущий токен этой установки. У Сары по-прежнему один аккаунт, но система отслеживает два отдельных места, куда могут прийти уведомления.
Хорошая таблица устройств обычно хранит:
- user ID
- стабильный ID устройства или установки
- текущий push-токен
- время последней проверки приложения
- флаг выхода из аккаунта или время выхода
Ночью на новом телефоне устанавливается обновление приложения. Сервис push обновляет его токен. Если приложение отправляет этот новый токен с тем же install ID, backend должен обновить существующую строку для нового телефона, а не создавать вторую активную строку для той же установки.
Именно в этой мелочи начинаются многие ошибки токенов push-уведомлений. Если backend оставит и старый, и новый токен активными, Сара может получить дублирующиеся уведомления на новом телефоне. Если система перезапишет не ту строку, можно перестать отправлять на новый телефон и продолжить слать на мертвый токен.
На следующий день Сара выходит из аккаунта на старом телефоне, но остается в системе на новом. Backend должен пометить как вышедший только старый телефон. Он не должен удалять все токены, связанные с аккаунтом Сары.
Во время отправки чистая таблица дает один понятный ответ: отправлять уведомление только на новый телефон. Старый телефон исключается, потому что Сара вышла из него, а новый остается, потому что его токен актуален и сеанс все еще активен.
Грязный список токенов ломает это очень быстро. Один неверный запрос может отправить сообщение на оба телефона, хотя один уже вышел из аккаунта. Другой неверный запрос может удалить все строки Сары и пропустить оба телефона в следующей кампании.
Если потом провайдер отклонит старый токен Сары, пометьте как недействительной только эту запись устройства. Не наказывайте за это другой телефон. За неделю один пользователь может накопить удивительно много старых токенов, если просто добавлять строки и никогда не чистить их.
Ошибки, которые команды продолжают выпускать
Многие ошибки токенов push-уведомлений начинаются с одного плохого shortcut: приложение хранит один токен в записи пользователя и считает задачу решенной. На демо это работает. А вот в тот момент, когда один человек входит на втором телефоне, переустанавливает приложение или использует и планшет, и ноутбук, все ломается.
Потом новый токен перезаписывает старый, и никто этого не замечает. Одно устройство перестает получать уведомления, поддержка слышит: «Уведомления приходят как попало», а команда винит провайдера вместо модели данных.
Еще одна тихая проблема — отсутствие временных меток. Если вы не храните, когда приложение последний раз подтвердило токен, вы не можете отличить «все еще активно» от «вероятно, мертво». Старые записи месяцами лежат в базе, кампании выглядят крупнее, чем есть на самом деле, а цифры доставки начинают врать.
Выход из аккаунта тоже создает проблемы. Многие команды очищают локальные данные приложения, но оставляют серверный токен привязанным к старому аккаунту. Так и возникают проблемы с уведомлениями после выхода. Общий семейный планшет, тестовое устройство или телефон сотрудника могут еще долго получать сообщения для чужого пользователя.
Повторы делают ситуацию хуже. Если worker продолжает повторять отправки на мертвые токены, не помечая их как неудачные, система создает ложное чувство контроля. Очередь движется, но повторное вовлечение проседает неделя за неделей, потому что никто не закрывает цикл обратной связи от провайдера.
QA часто все это пропускает, потому что тестовый путь слишком чистый. Один тестировщик, один телефон, один аккаунт, одна свежая установка. Реальные пользователи ведут себя сложнее:
- входят в систему на двух устройствах
- переключают аккаунты на одном и том же телефоне
- удаляют и устанавливают приложение заново после обновления
- надолго исчезают, а потом возвращаются
- оставляют старую запись токена после выхода из аккаунта
Если хотите простое правило, относитесь к токенам как к записям уровня устройства, а не как к флажкам уровня пользователя. Храните время последней активности. Отвязывайте токены при выходе из аккаунта. Быстро помечайте ошибки провайдера. Тестируйте двумя телефонами и одним аккаунтом, а потом одним телефоном и двумя аккаунтами. Такое небольшое изменение ловит баги, которые тихо съедают результаты кампаний.
Быстрые проверки перед каждой кампанией
Кампания push может выглядеть нормально в дашборде и все равно не дойти до многих реальных пользователей. Большинство ошибок токенов push-уведомлений проявляются как небольшие разрывы: принятые отправки, которые так и не доходят до телефона, старые токены, привязанные к мертвым сеансам, или один человек, у которого второе устройство перестало получать уведомления несколько недель назад.
Каждый раз перед широкой рассылкой проводите короткую проверку. Обычно достаточно 15 минут.
- Сравните количество подготовленных отправок с тем, что принимает ваш провайдер push. Если вы планировали 50 000 отправок, а приняли только 46 000, остановитесь и выясните почему, прежде чем делать выводы о доставке или открытиях.
- Возьмите несколько аккаунтов, где используются два устройства. Убедитесь, что на обоих телефонах есть активные токены и оба токена все еще относятся к одному пользователю.
- Протестируйте вход, выход и повторный вход на iOS и Android. Посмотрите, куда попадает токен после каждого шага. Проблемы с уведомлениями после выхода часто начинаются тогда, когда приложение сохраняет старую связь между аккаунтом и токеном.
- Проверьте токены, которые старше обычного цикла визитов. Если активные пользователи открывают приложение раз в неделю или две, токен, который не менялся месяцами, не должен лежать в той же корзине, что и свежий.
- Найдите дублирующиеся токены, привязанные к разным аккаунтам. Обычно это означает, что backend неправильно объединил записи, поток выхода из аккаунта неполный или приложение переиспользовало локальное состояние.
Еще одна проверка очень помогает: отправьте реальное тестовое сообщение маленькой группе внутренних пользователей перед полной кампанией. Возьмите одного человека с двумя телефонами, одного человека, который недавно вышел из аккаунта, и одного человека, который давно не открывал приложение. Убедитесь, что правильный аккаунт получает сообщение на правильном устройстве.
Если какая-то из этих проверок не проходит, поставьте кампанию на паузу. Плохие данные о токенах не только снижают доставку. Они могут отправить не то уведомление не тому аккаунту, и пользователи это быстро замечают.
Что исправить дальше
Большинству команд не нужен полный пересбор. Им нужна более чистая запись о том, какое устройство принадлежит какому пользователю, когда эта запись менялась и почему. Если после кампании вы все еще видите ошибки токенов push-уведомлений, начните с модели данных и цепочки событий, а не с текста кампании.
Хороший первый шаг специально скучный. Сделайте так, чтобы каждая запись токена отвечала на несколько простых вопросов: какая установка приложения его создала, какому устройству он принадлежит, какой пользователь сейчас вошел в систему, когда токен менялся последний раз и отклонил ли его уже провайдер. Если схема не может быстро ответить на эти вопросы, ошибки прячутся в пробелах.
Затем протестируйте потоки, которые обычно ломают продакшн-данные:
- обновление токена после обновления приложения или смены ОС
- выход пользователя на одном устройстве и вход под другим аккаунтом
- переустановка приложения, которая создает новый токен для того же телефона
- переключение аккаунтов на общих устройствах
- один и тот же пользователь, вошедший сразу на двух телефонах
Не останавливайтесь на ручном тесте. Логируйте каждое событие по порядку, чтобы команда видела всю цепочку: токен создан, токен обновлен, токен привязан к пользователю, токен отвязан при выходе, токен помечен провайдером как недействительный. Когда сработает alert, эта хронология сэкономит часы.
Настройте один простой мониторинг обратной связи от провайдера. Внезапный всплеск недействительных или незарегистрированных токенов часто означает сломанный поток обновления токена, плохой релиз или ошибку выхода, которая оставила старые записи устройств. Поймать это в тот же день намного дешевле, чем потом гадать, почему повторное вовлечение упало на две недели.
Ежемесячная очистка тоже помогает. Проверяйте неактивные токены, которые давно не открывали приложение, не обновлялись и не принимали уведомления. Не удаляйте их вслепую, но убирайте из активных рассылок, пока они не докажут, что все еще должны там быть. Это делает аудиторию чище, а статистику доставки честнее.
Если ваша команда уже чинила одну и ту же проблему дважды, попросите еще одну пару глаз посмотреть на весь pipeline. Oleg на oleg.is разбирает системы уведомлений с учетом краевых случаев аккаунта, устройства и авторизации, которые команды часто пропускают, особенно когда у одного пользователя несколько устройств, а старые токены продолжают висеть.
Сначала исправьте учет записей. После этого кампании обычно восстанавливаются.