Не так давно 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 уведомления.
Поделиться с друзьями
-->

Комментарии (17)


  1. kostya_bakay
    27.05.2016 19:29
    +1

    Еще не изучал Firebase, но в будущем хочу, поэтому хотелось бы еще видеть такие статьи.


  1. petrovichtim
    28.05.2016 05:23
    +1

    Подскажите как быть со старой аналитикой?
    Она же так же через json настраивается.
    Может от старой вообще отказаться?


    1. svoka
      28.05.2016 11:23
      +1

      Гугл рекомендует плавно переезжать.
      В Firebase тоже есть аналитика и судя по описанию возможностей даже больше.
      Но честно: пока не копал :)


    1. kaftanati
      29.05.2016 23:01

      Буквально сегодня подключал FireBase — при создании проекта можно импортировать существующее приложение — оно автоматически подтянет настройки Google Аналитики и ДОпишет идентификатор в json файл настроек — в итоге работает и старая аналитика и новая.

      Но пришлось повозиться с управлением проектами (их полный перечень можно найти в https://console.developers.google.com/iam-admin).


      1. almkhaj
        30.05.2016 08:27

        Привязал приложение через Admob (автоматически создает проект в firebase). У меня возникла проблема: зависание после внедрения firebase analytics в момент вызова intent-а Galery (точнее уже после выбора изображения). Убираю firebase analytics — все работает. Экспериментировал только на эмуляторе. А как у Вас?
        Еще, не знаете ли можно ли безболезненно удалить проект из firebase? — очень уж страшное предупреждение.


        1. kaftanati
          30.05.2016 09:08

          Я случайно приимпортировал проект к другому аккаунту. Пришлось удалить. Тоже напугало такое предупреждение, но решил, что смогу приимпортировать заново к другому аккаунту. Фиг. Не получается. Решил проблему так:

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

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

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

          P.S. Может вы нашли — в гугл аналитике очень удобно смотреть выкладку «в текущий момент — пользователи/экраны/устройства». В FireBase не нашел. Да и на первый взгляд меньше возможностей, несмотря на новые встроенные триггеры из приложения — удалено/сброс данных/устройство обновилось/первый запуск. Так и задумано?


          1. almkhaj
            30.05.2016 09:56

            Спасибо за развернутый ответ. Похоже, лучше проект не удалять.
            В firebase-аналитике мне понравилась возможность UserProperty и расширение отправки информации с events (Bundle).
            К сожалению, плотно с firebase пока не было времени разбираться. Завел туда приложение только для эксперимента с внедрением. Кстати, после возвращения на GA (с залитием соответсвующего json), проблема у меня не исчезла. Пока пришлось отключить аналитику.


            1. kaftanati
              30.05.2016 10:44

              Может дело в обновленной библиотек аналитики и сервисов 9.0.*. Я использую 9.0.1 — буквально вчерашняя версия. Пробовали откатится или обновить до последней?


              1. almkhaj
                30.05.2016 18:48

                В общем, сам виноват. Нашел ответ на stackoverflow. Заменил «com.google.android.gms:play-services:9.0.1» на только необходимые.


  1. loredan13
    28.05.2016 11:20
    +1

    По поводу смены иконки: насколько я понял, параметр icon в API аналогичен setSmallIcon в Notification.Builder, и какого-либо способа задать LargeIcon нет. Однако я также обнаружил, что если в запросе к API нет объекта notification, то onMessageReceived срабатывает даже если приложение находится в фоне


    1. svoka
      28.05.2016 11:22
      +1

      Да, все правильно. Если нужно всегда обрабатывать с помощью onMessageReceived, то нужно посылать Data-сообщения.
      Спасибо за дополнение!


  1. pavel_dolbik
    28.05.2016 12:04
    +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


    1. svoka
      28.05.2016 13:34

      Именно об этом я и писал в конце поста :)

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

      В FCM это можно обойти, если отправлять data-сообщение, как раз как в вашем примере.
      Из консоли сейчас отправляются notification-сообщения.


      1. loredan13
        28.05.2016 15:52

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

        Однако убрать notification при отправке через консоль все равно пока нельзя


        1. svoka
          29.05.2016 00:44

          Да, консоль пока строго notification. Обещают вскоре поправить :)


      1. Link20
        29.05.2016 00:43

        data-сообщения в Android также прекрасно (независимо от статуса приложения) обрабатывается в onMessageReceived и для GCM.


  1. FirsofMaxim
    28.05.2016 15:56

    Спасибо! Эх где вы были недельку назад?! :)
    PS: еще не сразу понял как создавать topic, в Firebase console есть опция отправить через topic, но создать — увы! Решается все просто: в приложении подписываемся на топик с нужным именем (как в стандартном примере) и вуаля через сутки он появляется в Firebase console.