Чому 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 так, щоб дані оновлювалися навіть у найжорсткіших умовах.







