Push уведомления в Android с помощью Firebase Cloud Messaging для начинающих

Не так давно Google купили Firebase и теперь на странице с описанием GCM нас встречает радостная новость о том, что пора бы мигрировать на Firebase.
...GCM users are strongly recommended to upgrade to FCM, in order to benefit from new FCM features today and in the future.

В этой статье мы разберем тестовый проект и рассмотрим один подводный камень связанный с иконкой уведомления.

Нам понадобится:

  • Android Studio
  • Код демо-проекта с github
  • 20 минут свободного времени

Шаг 1.

Скачайте демо-проект и откройте его в своей любимой Android Studio.

Шаг 2.

Теперь нам нужно пойти в Firebase console и добавить наш проект.



Затем нажимаем «Добавьте Firebase в свое приложение для Android».



Название пакета, если вы все делаете по манула: «com.google.firebase.quickstart.fcm».

На втором шаге скачиваем файл google-service.json и добавляем его к проекту.



Нажимаем готово, зависимости уже добавлены в тестовом проекте.

Шаг 3.

Подготовительная часть закончена, можно нажимать кнопку «Запустить приложение»

В процессе компиляции вы можете получить 2 ошибки:

Missing api_key/current key with Google Services 3.0.0

В этом случае вам нужно зайти в настройки проекта и перезакачать файл google-service.json. Это странный баг, но благо легко лечится.

Вторая ошибка — это:

Failed to resolve: com.google.firebase:firebase-core:9.0.0

Тогда вам нужно обновить Google Play Service и Google Repository. Ссылка на Stackoverflow.

После запуска приложения, в Android monitor увидите наш токен. Можно отправляться тестировать. Идем в консоль, ищем наше приложение, и идем в раздел Grow->Notifications:



Нажимаем создать сообщение:



Вводим наши данные, нажимаем отправить и наблюдаем в Android monitor как все пришло.

Теперь к самому интересному

Самый частый вопрос: как поменять иконку уведомления, когда приложение работает в бэкграунде?

Дело в том, что когда приложение находится в бэкграунде, то оно отправляется сразу в Notification center, и функция

onMessageReceived

не срабатывает.

Чтобы использовать свои иконки уведомлений, вам нужно посылать сообщение через API, через консоль такая кастомизация на данный момент не работает.

UPD: Если вы хотите, чтобы все ваши сообщения даже когда приложение в background или убито, обрабатывались с помощью
onMessageReceived

в приложении, то отправляйте data-сообщения, т.е. без секции notification

Ссылка на API. Для тестов можно использовать старый-добрый CURL.

Еще одна полезная ссылка

Вот в целом и все, что вам нужно знать чтобы попробовать новые push уведомления.
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 17
  • +1
    Еще не изучал Firebase, но в будущем хочу, поэтому хотелось бы еще видеть такие статьи.
    • +1
      Подскажите как быть со старой аналитикой?
      Она же так же через json настраивается.
      Может от старой вообще отказаться?
      • +1
        Гугл рекомендует плавно переезжать.
        В Firebase тоже есть аналитика и судя по описанию возможностей даже больше.
        Но честно: пока не копал :)
        • 0
          Буквально сегодня подключал FireBase — при создании проекта можно импортировать существующее приложение — оно автоматически подтянет настройки Google Аналитики и ДОпишет идентификатор в json файл настроек — в итоге работает и старая аналитика и новая.

          Но пришлось повозиться с управлением проектами (их полный перечень можно найти в https://console.developers.google.com/iam-admin).
          • 0
            Привязал приложение через Admob (автоматически создает проект в firebase). У меня возникла проблема: зависание после внедрения firebase analytics в момент вызова intent-а Galery (точнее уже после выбора изображения). Убираю firebase analytics — все работает. Экспериментировал только на эмуляторе. А как у Вас?
            Еще, не знаете ли можно ли безболезненно удалить проект из firebase? — очень уж страшное предупреждение.
            • 0
              Я случайно приимпортировал проект к другому аккаунту. Пришлось удалить. Тоже напугало такое предупреждение, но решил, что смогу приимпортировать заново к другому аккаунту. Фиг. Не получается. Решил проблему так:

              — проекты сразу не удаляются, а висят еще неделю в консоли AIM
              — я восстановил все проекты, которые нужны и уже вытянули всю статистику
              — там же. в AIM консоли добавил все рабочие аккаунты в перечень владельцев, и потом переключив пользователя, убрал права у изначального пользователя-инициатора проекта
              — таким образом у необходимого пользователя собрал все проекты после импорта. Пустые дубликаты висят в списке на удаление.

              Интересно, что если после удаления проекта (после удачного импорта) повторно импортировать не получается — только создать. Но при этом выдаются новые id приложения, никак автоматически приложения не увязываются c Google Developer Console и Google Analytics.
              Поэтому если проект уже приимпортирован рабочий, осторожно — не удаляйте. Просто уберите из json лишнюю аналитику и настройки FireBase сбора данных.

              Тестировал аналитику на устройствах — проблем с файловыми интентами не заметил. Но без разрешения для проекта в AIM консоли на отсылку отчетов о крашах «Mobile Crash Analytics» отказывался их слать в FireBase.

              P.S. Может вы нашли — в гугл аналитике очень удобно смотреть выкладку «в текущий момент — пользователи/экраны/устройства». В FireBase не нашел. Да и на первый взгляд меньше возможностей, несмотря на новые встроенные триггеры из приложения — удалено/сброс данных/устройство обновилось/первый запуск. Так и задумано?
              • 0
                Спасибо за развернутый ответ. Похоже, лучше проект не удалять.
                В firebase-аналитике мне понравилась возможность UserProperty и расширение отправки информации с events (Bundle).
                К сожалению, плотно с firebase пока не было времени разбираться. Завел туда приложение только для эксперимента с внедрением. Кстати, после возвращения на GA (с залитием соответсвующего json), проблема у меня не исчезла. Пока пришлось отключить аналитику.
                • 0
                  Может дело в обновленной библиотек аналитики и сервисов 9.0.*. Я использую 9.0.1 — буквально вчерашняя версия. Пробовали откатится или обновить до последней?
                  • 0
                    В общем, сам виноват. Нашел ответ на stackoverflow. Заменил «com.google.android.gms:play-services:9.0.1» на только необходимые.
        • +1
          По поводу смены иконки: насколько я понял, параметр icon в API аналогичен setSmallIcon в Notification.Builder, и какого-либо способа задать LargeIcon нет. Однако я также обнаружил, что если в запросе к API нет объекта notification, то onMessageReceived срабатывает даже если приложение находится в фоне
          • +1
            Да, все правильно. Если нужно всегда обрабатывать с помощью onMessageReceived, то нужно посылать Data-сообщения.
            Спасибо за дополнение!
          • +1
            Еще нужно упомянуть про различия в работе FCM когда приложение работает в foreground и background.

            Когда вы используете FCM вам нужен сервис, который будет отвечать за прием сообщений (callback — https://developers.google.com/cloud-messaging/android/android-migrate-fcm#update_your_instanceidlistenerservice)


            public class MyFcmListenerService extends FirebaseMessagingService {
              @Override
              public void onMessageReceived(RemoteMessage message){
                String from = message.getFrom();
                Map data = message.getData();
              }
              ...
            }
            



            И как только отработает этот метод, мы можете сформировать нотификацию.
            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.notification_icon)
                    .setContentTitle("My notification")
                    .setContentText("Hello World!");
            



            Когда ваше приложение запущено(работает) и для отправки уведомлений вы используете — <a href=«https://console.firebase.google.com/?pli=1»
            Все работает прекрасно: метод onMessageReceived отрабатывает и вы видете свое кастомизированные уведомление.

            Но стоит вам свернуть приложение и проделать все тоже самое — никакой вибрации, никакого звука уведомлений вы не увидете. Мало того, если будет использован android 5 и выше увидете белый квадрат, в статус баре, т.к. андройд возьмет иконку вашего приложения и зальет ее белым цветом.
            В такой ситуации метод onMessageReceived не отрабатывает =(

            Решение оказалось простым — <a href=«https://firebase.google.com/docs/cloud-messaging/downstream#sending_topic_messages_from_the_server
            Для тестирования можно воспользоваться fiddler2

            https://fcm.googleapis.com/fcm/send
            Content-Type:application/json
            Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
            
            { "data": {
                "score": "5x1",
                "time": "15:10"
              },
              "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
            }
            


            Где — Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA, можно взять из google-service.json
            »to": «bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...» — это токен вашего устройства, который получается из метода — onTokenRefresh() из сервиса FirebaseInstanceIdService — https://developers.google.com/cloud-messaging/android/android-migrate-fcm#update_your_instanceidlistenerservice
            • 0
              Именно об этом я и писал в конце поста :)

              Но давайте будем честны, в GCM ровно такое же поведение: если приложение в foreground — onMessageReceived, если в background или убито, то сообщение направляется в Notification center.

              В FCM это можно обойти, если отправлять data-сообщение, как раз как в вашем примере.
              Из консоли сейчас отправляются notification-сообщения.
              • 0
                Должен заметить, что строгого разделения на data-сообщения и notification-сообщения нет. В консоли Firebase при создании нового сообщения можно задать пользовательские данные, которые передаются как data в дополнение к notification. Через API также можно отправлять сообщение с data и notification одновременно.

                Однако убрать notification при отправке через консоль все равно пока нельзя
                • 0
                  Да, консоль пока строго notification. Обещают вскоре поправить :)
                • 0
                  data-сообщения в Android также прекрасно (независимо от статуса приложения) обрабатывается в onMessageReceived и для GCM.
              • 0
                Спасибо! Эх где вы были недельку назад?! :)
                PS: еще не сразу понял как создавать topic, в Firebase console есть опция отправить через topic, но создать — увы! Решается все просто: в приложении подписываемся на топик с нужным именем (как в стандартном примере) и вуаля через сутки он появляется в Firebase console.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.