Разработка для мобильных платформ в экосистеме 1С имеет свои уникальные особенности, особенно когда речь заходит о взаимодействии с операционной системой в фоновом режиме. Одной из самых востребованных функций является система уведомлений. В данной статье мы подробно разберем, как заставить мобильное приложение 1С «общаться» с пользователем, когда оно закрыто или находится в фоне, и почему стандартные методы не всегда срабатывают с первого раза.
Прежде всего, нам необходимо четко разделить два типа уведомлений, доступных в мобильной платформе 1С:
Рассмотрим пошагово реализацию каждого механизма.
Одной из главных причин, по которой локальные уведомления не приходят вовремя (или не приходят вовсе), является некорректная работа с часовыми поясами. Мобильная платформа 1С требует указывать время срабатывания в формате Универсального координированного времени (UTC).
Разберем типичный пример кода, который позволяет запланировать уведомление. Мы будем использовать объект ДоставляемоеУведомление и метод глобального контекста ДоставляемыеУведомления.ДобавитьЛокальноеУведомление().
#Если МобильноеПриложениеКлиент Тогда
Уведомление = Новый ДоставляемоеУведомление;
Уведомление.Заголовок = "Напоминание от 1С";
Уведомление.Текст = "Пора проверить текущие остатки на складе!";
// Важнейший момент: преобразуем местное время в UTC
// Если этого не сделать, уведомление может сработать со смещением в несколько часов
ДатаСобытия = Дата("20231201120000"); // 12:00 по местному времени
Уведомление.ДатаПоявленияУниверсальноеВремя = УниверсальноеВремя(ДатаСобытия);
Уведомление.ЗвуковоеОповещение = ЗвуковоеОповещение.ПоУмолчанию;
Уведомление.Наклейка = 1; // Число на иконке приложения
ДоставляемыеУведомления.ДобавитьЛокальноеУведомление(Уведомление);
// Подключаем обработчик, который выполнится при нажатии на уведомление
ДоставляемыеУведомления.ПодключитьОбработчикУведомлений("ПриПолученииУведомления");
#КонецЕсли
Проанализируем ситуацию, когда уведомления приходят «хаотично». В мобильных устройствах даты хранятся в универсальном формате, а отображаются согласно настройкам часового пояса. Если вы находитесь в поясе UTC+4 и устанавливаете ДатаПоявленияУниверсальноеВремя без преобразования, система может посчитать, что событие должно произойти через 4 часа или уже произошло 4 часа назад. Всегда используйте функцию УниверсальноеВремя() для точности.
Чтобы приложение отреагировало на открытие пользователем уведомления, необходимо реализовать процедуру-обработчик. Она должна располагаться в модуле управляемого приложения и быть экспортной.
Процедура ПриПолученииУведомления(Уведомление, Локально, Показано) Экспорт
Если Локально Тогда
// Логика обработки локального уведомления
ТекстСообщения = "Вы открыли локальное уведомление: " + Уведомление.Текст;
Сообщить(ТекстСообщения);
Иначе
// Логика обработки Push-уведомления
Сообщить("Прибыло Push-уведомление с данными: " + Уведомление.Данные);
КонецЕсли;
КонецПроцедуры
Для реализации Push-уведомлений нам понадобится посредник — Firebase Cloud Messaging (FCM). Процесс состоит из двух этапов: получение идентификатора устройства на стороне мобильного приложения и отправка запроса из центральной базы.
Шаг 1: Получение токена (идентификатора подписчика) в мобильном приложении. По аналогии с получением токенов в RuStore, нам нужно сообщить центральной базе, куда именно отправлять уведомление. Для реализации серверной части обмена данными подойдёт HTTP API сервис для взаимодействия с мобильным приложением.
#Если МобильноеПриложениеКлиент Тогда
// Номер проекта из консоли Firebase (Sender ID)
НомерПриложенияGoogle = "123456789012";
Попытка
ИдентификаторПодписчика = ДоставляемыеУведомления.ПолучитьИдентификаторПодписчикаУведомлений(НомерПриложенияGoogle);
// Передаем этот ID в центральную базу (используя HTTP API сервис задач или обмен данными)
ПередатьТокенНаСервер(ИдентификаторПодписчика.ИдентификаторУстройства);
Исключение
ЗаписьЖурналаРегистрации("Ошибка получения PUSH-токена", УровеньЖурналаРегистрации.Ошибка);
КонецПопытки;
#КонецЕсли
Шаг 2: Отправка Push-уведомления из серверной 1С. Рассмотрим пример функции, которая формирует HTTP-запрос к API Firebase (используя Legacy API ключ). Для предварительной отладки таких запросов удобно использовать Post1С - инструмент для тестирования REST API — для этого есть инструмент Post1С для анализа HTTP-запросов.
Функция ОтправитьPushAndroid(МассивТокенов, Заголовок, Текст)
КлючСервера = "ВАШ_API_KEY_ИЗ_КОНСОЛИ_FIREBASE";
СоединениеHTTP = Новый HTTPСоединение("fcm.googleapis.com", 443,,,,, Новый ЗащищенноеСоединениеOpenSSL());
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "key=" + КлючСервера);
Заголовки.Вставить("Content-Type", "application/json");
// Формируем структуру сообщения
ДанныеУведомления = Новый Структура;
ДанныеУведомления.Вставить("title", Заголовок);
ДанныеУведомления.Вставить("text", Текст);
ДанныеУведомления.Вставить("sound", "default");
ПараметрыJSON = Новый Структура;
ПараметрыJSON.Вставить("registration_ids", МассивТокенов);
ПараметрыJSON.Вставить("data", ДанныеУведомления);
ЗапросHTTP = Новый HTTPЗапрос("fcm/send", Заголовки);
ЗапросHTTP.УстановитьТелоИзСтроки(ЗаписатьJSON(ПараметрыJSON), "UTF-8");
Ответ = СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTP);
Возврат Ответ.КодСостояния; // 200 означает успех
КонецФункции
Если код написан верно, а телефон «молчит», проанализируем следующие факторы:
POST_NOTIFICATIONS. Без этого системного диалога и согласия пользователя уведомления будут блокироваться на уровне ОС.ПриПолученииУведомления. Для тестирования всегда сворачивайте приложение или блокируйте экран.Разберем еще один нюанс: свойство Данные в новых версиях платформы (8.3.20+) теперь представляет собой Соответствие. Если вы передаете сложные структуры из FCM, убедитесь, что на стороне мобильного клиента вы извлекаете их методом Уведомление.Данные.Получить("ИмяКлюча").
Используя предложенные методики и уделяя внимание работе с UTC, вы сможете создать надежную систему оповещений, которая будет работать стабильно независимо от состояния мобильного приложения. При необходимости можно воспользоваться готовым решением для отправки Push-уведомлений через FCM.