Как работает push-сервис в Android, когда приложение не запущено
Что проверяют
Понимаете ли вы, что приложение не держит своё соединение с сервером и кто на самом деле будит процесс. Следом обычно спрашивают разницу между notification и data сообщениями и что будет после принудительной остановки приложения.
Как отвечать
Схема такая: бэкенд отправляет сообщение в Firebase Cloud Messaging через HTTP v1 API, FCM доставляет его на устройство по одному постоянному соединению, которое Google Play services держат за все приложения сразу. Система поднимает процесс приложения, даже выгруженный, и передаёт сообщение в FirebaseMessagingService.
Важен тип сообщения:
- notification message: если приложение в фоне, уведомление в шторку показывает сам SDK,
onMessageReceived()не вызывается. Данные из блокаdataпопадут в extras интента, только когда пользователь нажмёт на уведомление; - data message:
onMessageReceived()вызывается в любом состоянии, уведомление вы собираете сами черезNotificationCompat.Builder. Полезная нагрузка до 4 КБ; - окно выполнения: на обработку даётся несколько секунд. Загрузку картинки или синхронизацию выносят в
WorkManager.
Назовите ограничения платформы. Сообщения с normal priority в режиме Doze ждут окна обслуживания, high priority будят устройство сразу, но если они регулярно не заканчиваются показом уведомления, FCM может понижать их приоритет. С Android 13 для показа уведомлений нужно runtime-разрешение POST_NOTIFICATIONS, а с Android 8 важность задаёт канал, а не setPriority. Токен меняется, и onNewToken() должен отправлять новый на бэкенд.
Для российского рынка упомяните устройства без Google-сервисов: там FCM не работает, нужны альтернативы вроде RuStore Push или Huawei Push Kit.
Где спотыкаются
Шлют notification message и ждут, что в фоне сработает onMessageReceived(). Для своей логики нужен data message.
Не знают про принудительную остановку. После «Остановить» в настройках приложение не получает сообщения, пока пользователь сам его не откроет. Похоже ведут себя агрессивные энергосбережения некоторых производителей.
Делают в onMessageReceived() сетевой запрос или тяжёлую работу: система может убить процесс раньше, чем появится уведомление.