Я разрабатываю приложение чата с использованием базы данных Firebase в Android.
Я уже выполнил основное (чат и действия со списком пользователей), но еще не создал систему уведомлений.
Я хочу, чтобы когда пользователь добавлялся к беседе (одиночной или групповой), а другой пользователь записывает новое сообщение в беседу, первый пользователь должен получать уведомление, которое при нажатии открывает активность беседы.
Моя большая дилемма заключается в том, как структурировать службу, которая работает в фоновом режиме, для получения push-уведомления или для прослушивания узла базы данных firebase, на который мне нужно посмотреть, чтобы узнать, есть ли какие-либо сообщения.
Я придумал два разных подхода:
Подход 1. Используйте уведомление firebase
При таком подходе я просто отправляю уведомление о данных от клиента-отправителя всем другим клиентам в разговоре, когда отправитель отправляет сообщение, и поэтому получатель решает показать уведомление (если активность в чате он не открыт) и обработать действие щелчка.
Думаю, с таким подходом я сэкономлю потребление ЦП, а затем и батарею.
Я не понимаю, как зарегистрировать пользователя для получения группового уведомления (уведомления темы), потому что, как я понял, я должен подписать этого клиента на тему, но если приложение работает в фоновом режиме или закрыть, откуда ему известно, что новая группа с пользователем внутри создана и поэтому она должна подписаться на эту тему? Для сценария разговора с двумя пользователями это не проблема, поскольку я могу отправить уведомление непосредственно целевому пользователю без подписки на какую-либо тему.
Подход 2) Прослушивание узла данных базы данных firebase в фоновой службе
При таком подходе мне просто нужно создать загрузочную службу, которая прослушивает определенный узел базы данных (с помощью ValueEventListener) и показывает уведомление, когда данные показывают, что приходит новое сообщение / диалог. Примером узла для прослушивания могут быть следующие данные о невидимых сообщениях:
conversation_user_unseen_messages
$conversationId1
$user1: 3
$conversationId2
$user2: 1
Затем, если данные показывают новые сообщения / разговоры, клиент приложения Android решит показать системное уведомление.
Я думаю, что при таком подходе будет больше потребление энергии, так как он должен постоянно проверять, есть ли какие-либо новые сообщения в базе данных.
Окончательное рассмотрение
Я нашел очень полезное руководство, написанное мифическим Франк ван Пуффелен, который объясняет, как настроить нужную мне систему с использованием дополнительного серверного компонента (сервер node.js). Мой последний вопрос: нужно ли мне настраивать сервер? Что может быть лучше, чем обработка всего, выполняемая клиентами (например, с использованием HTTP-запросов)?
Какое решение вы считаете лучшим? Большое спасибо.
ИЗМЕНИТЬ
Я все еще разбираюсь в этом, но вот некоторые соображения.
Мне нужно запросить и использовать InstanceID
Идентификатор экземпляра предоставляет уникальный идентификатор для каждого экземпляра ваших приложений.
Поэтому я должен запросить InstanceID, когда пользователь подключен, и InstanceId доступен.
И тогда не используйте темы.
Тематические сообщения оптимизированы для пропускной способности, а не для задержки. Для быстрой и безопасной доставки на отдельные устройства или небольшие группы устройств нацеливайте сообщения на токены, а не на темы.
как сказано в руководстве по тематическим сообщениям, которое вместо этого предлагает нацелить сообщение на токены.
Для этого мне нужно собрать токен пользователя в ссылке на мою пользовательскую базу данных:
users: {
$userId1: {
name: "John",
email: "[email protected]",
token: "Ax8HiP3Edf7....",
}
}
а затем, когда мой клиент приложения отправляет новое сообщение, он также должен отправить уведомление для всех пользователей, участвующих в чате, что я уже могу сделать с моей текущей структурой базы данных.
Как мне обрабатывать и собирать запросы? Я реализую серверное приложение node.js, которое подключается к базе данных Firebase и прослушивает запросы уведомлений, сделанные приложением, а затем отправляет запрос уведомления с помощью http-вызова каждому приложение назначения.
Когда мне нужно регистрировать токен пользователя? Когда клиент приложения запускается в первый раз или когда истекает срок действия InstanceID (onTokenRefresh).
Это правильный способ сделать это?
ИЗМЕНИТЬ 2
Я обнаружил большую дыру в реализации FCM. Похоже, я не могу обрабатывать все уведомления, доставляемые приложениям iOs, которые не находятся на переднем плане.
Как указано в документации по уведомлению о данных
В iOS FCM сохраняет сообщение и доставляет его только тогда, когда приложение находится на переднем плане и установило соединение FCM. В Android клиентское приложение получает сообщение с данными в onMessageReceived () и может соответствующим образом обрабатывать пары ключ-значение.
И мне нужно поймать уведомление о данных, даже когда приложение находится в фоновом режиме, мне это нужно специально, потому что я хочу обновить счетчик значков на значке приложения, чтобы пользователь знал, сколько у него непрочитанных сообщений.
Теперь я пробую решение OneSignal, которое может получать уведомления даже в фоновом режиме, оно бесплатное и взаимодействует с GCM. Мне грустно, что я не остаюсь с Google, но если я не могу обновить счетчик значков с помощью FCM, мне придется искать другую сторону.
Любое рассмотрение будет оценено.