Почему silent push не доходит: кейсы из практики
Silent push — мощный инструмент фоновой синхронизации, но реализация полна подводных камней. По статистике, неправильная настройка silent push приводит к 40% недополученных уведомлений на Android и до 60% на iOS в сложных сценариях. Один из наших клиентов, сервис доставки на 500 000 пользователей, столкнулся с тем, что после обновления на Android 13 фоновые уведомления перестали пробуждать приложение — Doze Mode с новыми ограничениями блокировал high-priority сообщения из-за отсутствия вызова setForegroundAsync в expedited worker. Мы перенастроили обработку и добавили вызов — проблема решилась. В этой статье разберём, как гарантированно настроить фоновую синхронизацию без участия пользователя, и покажем, как избежать типовых ошибок. Наш опыт — 10+ лет в мобильной разработке, 50+ проектов с push-инфраструктурой.
Silent Push на iOS: технические нюансы
На iOS silent push требует флага content-available: 1 в payload и включённой Background Mode «Remote notifications» в Xcode Capabilities.
Payload APNs:
{ "aps": { "content-available": 1 }, "sync_type": "messages", "last_known_id": "msg_8823" } Без alert, без sound — чистый фоновый вызов. Обработка в AppDelegate:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { guard let syncType = userInfo["sync_type"] as? String else { completionHandler(.noData) return } Task { do { let hasNewData = try await SyncManager.shared.sync(type: syncType) completionHandler(hasNewData ? .newData : .noData) } catch { completionHandler(.failed) } } } Критический момент: iOS даёт около 30 секунд на выполнение. Если completionHandler не вызван — принудительное завершение. Также iOS не гарантирует доставку при низком заряде батареи (Low Power Mode) и после принудительного закрытия приложения. Force quit полностью блокирует silent push до ручного запуска — это документированное поведение iOS, обойти нельзя. Подробнее в официальной документации Apple.
Silent Push на Android: FCM Data Message и WorkManager
На Android роль silent push выполняет FCM Data Message — он попадает в FirebaseMessagingService.onMessageReceived независимо от состояния приложения (если не убит системой Doze).
class AppFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(message: RemoteMessage) { val syncType = message.data["sync_type"] ?: return val workRequest = OneTimeWorkRequestBuilder<SyncWorker>() .setInputData(workDataOf("sync_type" to syncType)) .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) .build() WorkManager.getInstance(applicationContext).enqueue(workRequest) } } setExpedited() запрашивает немедленное выполнение. На Android 12+ внутри expedited worker нужно вызвать setForegroundAsync(), иначе при долгой операции возможен ANR.
Doze Mode ограничивает фоновую активность. FCM high-priority сообщения обходят Doze, если в payload указать android.priority: "HIGH":
{ "message": { "token": "device_fcm_token", "android": { "priority": "HIGH" }, "data": { "sync_type": "messages", "payload": "{...}" } } } Дополнительно о Doze Mode
Doze Mode активируется, когда устройство неактивно и не подключено к зарядке. High-priority сообщения обходят его, но при очень частых запросах система может начать игнорировать их — соблюдайте интервалы не менее 10 минут между silent push.Как обновить badge без уведомления пользователя?
Популярный кейс — обновить цифру на иконке без показа уведомления. На iOS через silent push:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { if let badge = userInfo["badge"] as? Int { UNUserNotificationCenter.current().setBadgeCount(badge) { _ in } } completionHandler(.newData) } На Android единого API нет — используйте библиотеку ShortcutBadger или NotificationManagerCompat.setNumber(), но поддержка зависит от лончера (Samsung, Xiaomi, Huawei).
Ограничения и квоты
iOS 13+ ввёл BGTaskScheduler и background processing quota. Если приложение слишком часто запрашивает фоновое выполнение без пользы для пользователя, система начинает throttle-ить вызовы. Вызов completionHandler(.noData) при отсутствии новых данных критичен для корректной работы системы квот. На Android аналогичный механизм — WorkManager сжимает частые задачи. Соблюдайте интервалы и используйте экспоненциальную задержку при ошибках.
Сравнение платформ
| Характеристика | iOS | Android |
|---|---|---|
| Механизм | Silent Push (content-available) | FCM Data Message |
| Фоновое выполнение | Background Modes + 30с лимит | WorkManager + expedited |
| Force quit | Не доставляется | Доставляется (если не убит системой) |
| Doze Mode | Throttling по квоте | High priority обходит Doze |
| Badge обновление | UNUserNotificationCenter.setBadgeCount |
ShortcutBadger / лончер-специфично |
Типичные ошибки и решения
| Ошибка | Решение |
|---|---|
| Silent push не доставляется на iOS после force quit | Объясните пользователю, что приложение нужно запускать вручную |
| FCM Data Message не пробуждает на Android 12+ | Добавьте setForegroundAsync() в expedited worker |
| Badge не обновляется на Android Xiaomi | Используйте ShortcutBadger с явной поддержкой Xiaomi |
| Превышение квоты фонового выполнения на iOS | Уменьшите частоту silent push до 1 раза в 5-10 минут |
Что входит в настройку silent push под ключ
При заказе нашей услуги вы получаете:
- Проектирование архитектуры push-инфраструктуры (APNs + FCM)
- Реализацию обработчиков на iOS и Android с учётом граничных случаев
- Конфигурацию Background Modes, WorkManager, high-priority топиков
- Интеграцию обновления badge counter на обеих платформах
- Документацию и обучение вашей команды
- Поддержку после запуска (1 месяц)
Почему стоит доверить настройку нам?
Мы специализируемся на мобильной разработке с 10+ летним опытом. За это время реализовали более 50 проектов с push-инфраструктурой, включая высоконагруженные приложения с миллионами пользователей. Наши решения проходят App Store Review и Google Play Console без замечаний. Используем актуальные версии Swift, Kotlin, Flutter — стек подбирается под ваш проект.
Сроки и стоимость
Настройка silent push для одной платформы (iOS или Android) занимает 3–5 рабочих дней. Комплексное решение под обе платформы — от 5 до 9 дней. Стоимость рассчитывается индивидуально в зависимости от сложности интеграции и необходимого стека. Оценим ваш проект бесплатно — просто свяжитесь с нами.
Получите консультацию — пишите на почту или через форму на сайте. Поможем настроить silent push так, чтобы данные обновлялись даже в самых жёстких условиях.







