Значок уведомления с новой системой обмена сообщениями Firebase Cloud

Вчера Google представил на Google I / O новую систему уведомлений, основанную на новом Firebase. Я попробовал этот новый FCM (Firebase Cloud Messaging) с примером на Github.

Значок уведомления всегда является ic_launcher, несмотря на то, что я объявил конкретную возможность рисования

Почему ? Здесь ниже официальный код для обработки сообщения

public class AppFirebaseMessagingService extends FirebaseMessagingService {

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    // [START receive_message]
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // If the application is in the foreground handle both data and notification messages here.
        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.
        sendNotification(remoteMessage);
    }
    // [END receive_message]

    /**
     * Create and show a simple notification containing the received FCM message.
     *
     * @param remoteMessage FCM RemoteMessage received.
     */
    private void sendNotification(RemoteMessage remoteMessage) {

        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

// this is a my insertion looking for a solution
        int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.myicon: R.mipmap.myicon;
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(icon)
                .setContentTitle(remoteMessage.getFrom())
                .setContentText(remoteMessage.getNotification().getBody())
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

}

person marco    schedule 19.05.2016    source источник
comment
firebase не имеет ничего общего с тем, как ВЫ создаете уведомление, пожалуйста, предоставьте изображение того, что вы видите   -  person tyczj    schedule 19.05.2016
comment
точный. этот код поступает прямо из Firebase, а метод sendNotification () точно такой же для любого уведомления. Этот код отлично работает с GCM, но с FCM нет. он всегда остается ic_launcher, используя новый веб-интерфейс для отправки сообщений   -  person marco    schedule 19.05.2016
comment
вы устанавливаете маленький значок, но не большой значок, если только вы не отправляете push с тегом уведомления в полезных данных push, это не имеет ничего общего с FCM   -  person tyczj    schedule 19.05.2016
comment
Отображает ли он ваш пользовательский значок уведомления, когда приложение находится на переднем плане? Это подходит для меня. Однако, когда приложение работает в фоновом режиме, оно должно использовать какой-то обработчик FCM по умолчанию, поскольку все настройки уведомлений игнорируются (значок, звук, свет, вибрация и т. Д. Не могут быть настроены).   -  person shinypenguin    schedule 19.05.2016
comment
@shinypenguin, ты прав! Я не заметил, что даже другие параметры не могут быть изменены. И да, значок работает, когда приложение находится на переднем плане, как вы сказали.   -  person marco    schedule 19.05.2016
comment
codingaffairs.blogspot.com/2016/06/   -  person Developine    schedule 20.06.2016
comment
Это может происходить из-за того, что консоль firebase отправляет уведомление о другой структуре вместо данных, которые люди используют для управления уведомлением Android ... вы отправляете с консоли?   -  person superUser    schedule 20.07.2016


Ответы (10)


К сожалению, это было ограничением уведомлений Firebase в SDK 9.0.0-9.6.1. Когда приложение работает в фоновом режиме, значок запуска используется из манифеста (с необходимой тонировкой Android) для сообщений, отправленных с консоли.

Однако с SDK 9.8.0 вы можете изменить значение по умолчанию! В вашем AndroidManifest.xml вы можете установить следующие поля для настройки значка и цвета:

<meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/notification_icon" />
<meta-data android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/google_blue" />

Обратите внимание, что если приложение находится на переднем плане (или отправлено сообщение с данными), вы можете полностью использовать свою собственную логику для настройки отображения. Вы также всегда можете настроить значок при отправке сообщения из API HTTP / XMPP.

person Ian Barber    schedule 19.05.2016
comment
Спасибо за разъяснения, Ян - person marco; 19.05.2016
comment
@ Ян Барбер: есть ли у Google планы изменить это поведение в ближайшем будущем? - person skylve; 07.06.2016
comment
Команда знает об этой проблеме и работает над ее исправлением. - person Arthur Thompson; 08.06.2016
comment
Лучше использовать OneSignal для отправки push-уведомлений, которые также бесплатны. - person Passiondroid; 30.06.2016
comment
какие-нибудь обновления по этому поводу? думал, что спрошу, потому что были обстоятельства, когда инженер Google просто забыл запустить патч. - person CQM; 18.08.2016
comment
Та же проблема возникает в устаревшей библиотеке GCM. Firebase унаследовала его. - person Gabor; 25.08.2016
comment
@IanBarber, каков статус по этому вопросу? Я не хочу открывать новую проблему на github только по этому вопросу .... Есть что-нибудь, чтобы исправить это понимание? - person Maverick283; 24.09.2016
comment
Все еще продолжается - извините, процесс был довольно запутанным по ряду внутренних причин. Надеюсь, в следующем выпуске у нас будет такая возможность. - person Ian Barber; 26.09.2016
comment
На сегодняшний день текущее поведение (сообщение от Firebase Console, приложение в фоновом режиме) заключается в отображении значка приложения из манифеста. Но теперь он сохраняет свой цвет, а не сплющивается (возможно, до неразборчивого белого квадрата). Я даже не знал, что это возможно. Это как ожидалось? Хотя значок в строке состояния может быть более разборчивым, он определенно не соответствует спецификации для этой версии ОС. Почему Firebase не поддерживает концепцию тега значка уведомления в манифесте, как Parse? - person Groovee60; 05.10.2016
comment
На сегодняшний день для приложений в фоновом режиме он показывает почти неразборчивую версию значка приложения (цветного) в строке состояния. Когда вы скользите вниз, чтобы щелкнуть уведомление, вы видите значок в форме пончика. Белый кружок с прозрачным отверстием в центре. Интересно, как мы должны использовать это для производственной сборки. Поскольку firebase может получить доступ к значку приложения, почему он не позволяет нам объявить наш собственный значок уведомления в манифесте, как предложил Groovee60? - person X09; 07.10.2016
comment
@IanBarber Извините за дополнительную ошибку, но есть ли у вас статус по этому исправлению? Если нет, мы собираемся изменить наши уведомления, чтобы они всегда были сообщениями с данными, что кажется плохим взломом. - person Austyn Mahoney; 25.10.2016
comment
На самом деле это был хороший день для ошибок! В новом выпущенном сегодня SDK есть переопределение, и я обновил свой ответ. - person Ian Barber; 25.10.2016
comment
@IanBarber Отлично, спасибо! Как настроить значок при отправке из API? Это работает до v9.6.1? - person Austyn Mahoney; 25.10.2016
comment
Габор: лучше всего подать заявку в службу поддержки с указанием конкретных деталей вашего приложения: firebase.google .com / support / contact / Troubleshooting - person Ian Barber; 29.10.2016
comment
Остин: API см. https://firebase.google.com/docs/cloud-messaging/http-server-ref параметр значка - person Ian Barber; 29.10.2016
comment
Это мне не помогло. У меня все еще есть белый квадрат. Кроме того, как я могу переопределить или установить большой значок? Как называется этот ресурс? - person parohy; 16.11.2016
comment
То же, что здесь парохи. Используя 9.8.0, я все еще получаю белый квадрат, хотя я установил свой собственный значок в файле манифеста. - person zaifrun; 18.11.2016
comment
Ах, у меня получилось работать с 9.8.0. Чтобы помочь другим, помните, что ваш значок в строке состояния должен соответствовать требованиям: разработчик. android.com/guide/practices/ui_guidelines/. У меня нет, и поэтому firebase просто по умолчанию использует стандартный белый квадрат вместо использования значка, указанного в манифесте. - person zaifrun; 20.11.2016
comment
Если вы случайно попробуете это и обнаружите, что значок меньше, чем другие уведомления, убедитесь, что вы используете вектор с возможностью рисования (а не png). Это решило проблему для меня. - person riper; 28.12.2016
comment
Вибрация и звук по умолчанию также не работают, когда приложение находится в фоновом режиме, поскольку onMessageReceived (RemoteMessage remoteMessage) не вызывается. Есть ли аналогичный способ интегрировать звук уведомления по умолчанию и вибрацию при уведомлении. - person Ebin Joy; 28.04.2017
comment
Я пробовал и работает только на API 27 и выше. Когда я запускаю свое приложение на API 25, отображается значок по умолчанию, указанный в манифесте с помощью android:icon. - person fdermishin; 27.02.2018
comment
см. официальную документацию firebase.google.com / docs / cloud-messaging / android / - person Deni Erdyneev; 07.04.2018
comment
@IanBarber, я могу отобразить правильный значок, но почему он в оттенках серого? - person Bargain23; 27.04.2018
comment
Мне пришлось добавить tools: replace = android: resource в метаданные цвета notificaiton и xmlns: tools = schemas.android.com / tools, чтобы этот код работал. - person Necmettin Sargın; 11.11.2020
comment
Метаданные default_notification_icon работали нормально, после того как я сделал свои собственные Image Asset - Notification Icon в Android / app / src / main / res ... Но "@color/google_blue" не существует, согласно Android Studio ... Где это указать? - person Karolina Hagegård; 11.02.2021

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

Это поможет вам получить обратный вызов onMessageReceived независимо от того, находится ли ваше приложение в фоновом или переднем плане, и тогда вы сможете сгенерировать собственное уведомление.

person geekoraul    schedule 27.05.2016
comment
Это предлагаемое решение и в документации Firebase, вы можете показывать уведомление любым удобным для вас способом, если вы полагаетесь на push-данные вместо уведомления. - person racs; 30.05.2016
comment
да согласен. это следует отметить как правильный ответ. или мой ответ ниже :) - person Developine; 24.06.2016
comment
Нет, это невозможно для людей, которым необходимо поддерживать совместимость с другими клиентами / устаревшими версиями, которые ожидают уведомления. - person Gabor; 25.08.2016
comment
У нас есть приложения в производстве, которые уже ожидают push-уведомления, и мы расширили этот (сложный) компонент серверной части, чтобы добавить данные для новых клиентов. Но мы не можем удалить поддержку устаревших версий нашего приложения. - person Gabor; 11.10.2016
comment
О, я согласен. Это еще одна проблема. Я предлагаю внимательно прочитать документацию перед интеграцией. Также необходимо тщательно протестировать перед выпуском в производство. Этой проблемы можно было бы избежать, если бы приложение было протестировано задолго до запуска. В любом случае, тебе было чему поучиться. - person geekoraul; 11.10.2016
comment
Я указывал, что для вашего решения потребуется изменение серверной части, что иногда не подходит. - person Gabor; 27.10.2016

atm они работают над этой проблемой https://github.com/firebase/quickstart-android/issues/4

когда вы отправляете уведомление из консоли Firebase, по умолчанию использует значок вашего приложения, а система Android будет превращать этот значок в сплошной белый цвет на панели уведомлений.

Если вы недовольны этим результатом, вам следует реализовать FirebaseMessagingService и создавать уведомления вручную при получении сообщения. Мы работаем над тем, чтобы улучшить это, но пока это единственный способ.

изменить: с SDK 9.8.0 добавить в AndroidManifest.xml

<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/my_favorite_pic"/>
person Jan Hartwig    schedule 26.05.2016
comment
как отобразить панель уведомлений с настраиваемыми значками в зефире - person Harsha; 16.11.2016

Мое решение похоже на решение ATom, но проще в реализации. Вам не нужно создавать класс, который полностью затеняет FirebaseMessagingService, вы можете просто переопределить метод, который получает Intent (который является общедоступным, по крайней мере, в версии 9.6.1), и взять информацию, которая будет отображаться из дополнительных функций. «Хакерская» часть заключается в том, что имя метода действительно запутано и будет меняться каждый раз, когда вы обновляете SDK Firebase до новой версии, но вы можете быстро найти его, проверив FirebaseMessagingService с помощью Android Studio и ища общедоступный метод, который принимает намерение как единственный параметр. В версии 9.6.1 он называется zzm. Вот как выглядит мой сервис:

public class MyNotificationService extends FirebaseMessagingService {

    public void onMessageReceived(RemoteMessage remoteMessage) {
        // do nothing
    }

    @Override
    public void zzm(Intent intent) {
        Intent launchIntent = new Intent(this, SplashScreenActivity.class);
        launchIntent.setAction(Intent.ACTION_MAIN);
        launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* R    equest code */, launchIntent,
                PendingIntent.FLAG_ONE_SHOT);
        Bitmap rawBitmap = BitmapFactory.decodeResource(getResources(),
                R.mipmap.ic_launcher);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_notification)
                .setLargeIcon(rawBitmap)
                .setContentTitle(intent.getStringExtra("gcm.notification.title"))
                .setContentText(intent.getStringExtra("gcm.notification.body"))
                .setAutoCancel(true)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager)     getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}
person Carlo Conserva    schedule 17.10.2016
comment
gcm.notification.title для имени ключа на 100% безопасен для всех версий? - person pedroooo; 27.03.2017

Просто установите targetSdkVersion на 19. Значок уведомления будет цветным. Затем дождитесь, пока Firebase исправит эту проблему.

person rattisuk    schedule 20.06.2016
comment
: D Ух ты, а где список побочных эффектов? - person Eugen Pechanec; 09.07.2016
comment
@EugenPechanec: да, компромисс в том, что вы не сможете использовать API, доступный на 20+ - person benleung; 23.07.2016

Есть еще один некрасивый, но рабочий способ. Декомпилируйте FirebaseMessagingService.class и измените его поведение. Затем просто поместите класс в нужный пакет в приложении yout, и dex будет использовать его вместо класса в самой библиотеке обмена сообщениями. Это довольно просто и работает.

Есть способ:

private void zzo(Intent intent) {
    Bundle bundle = intent.getExtras();
    bundle.remove("android.support.content.wakelockid");
    if (zza.zzac(bundle)) {  // true if msg is notification sent from FirebaseConsole
        if (!zza.zzdc((Context)this)) { // true if app is on foreground
            zza.zzer((Context)this).zzas(bundle); // create notification
            return;
        }
        // parse notification data to allow use it in onMessageReceived whe app is on foreground
        if (FirebaseMessagingService.zzav(bundle)) {
            zzb.zzo((Context)this, intent);
        }
    }
    this.onMessageReceived(new RemoteMessage(bundle));
}

Это код из версии 9.4.0, метод будет иметь разные имена в разных версиях из-за обфускации.

person ATom    schedule 04.09.2016

если ваше приложение находится в фоновом режиме, значок уведомления будет установлен в методе получения сообщения, но если ваше приложение находится на переднем плане, значок уведомления будет тем, который вы определили в манифесте

введите здесь описание изображения

person brook    schedule 16.12.2017

Я запускаю свои уведомления из консоли FCM и через HTTP / JSON ... с тем же результатом.

Я могу обрабатывать заголовок, полное сообщение, но значок всегда является белым кружком по умолчанию:

снимок экрана с уведомлением

Вместо моего пользовательского значка в коде (setSmallIcon или setSmallIcon) или значка по умолчанию из приложения:

 Intent intent = new Intent(this, MainActivity.class);
    // use System.currentTimeMillis() to have a unique ID for the pending intent
    PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);

    if (Build.VERSION.SDK_INT < 16) {
        Notification n  = new Notification.Builder(this)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pIntent)
                .setAutoCancel(true).getNotification();
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //notificationManager.notify(0, n);
        notificationManager.notify(id, n);
    } else {
        Bitmap bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

        Notification n  = new Notification.Builder(this)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setSmallIcon(R.drawable.ic_stat_ic_notification)
                .setLargeIcon(bm)
                .setContentIntent(pIntent)
                .setAutoCancel(true).build();

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //notificationManager.notify(0, n);
        notificationManager.notify(id, n);
    }
person Gonzalo    schedule 22.05.2016
comment
Понятно! мои теги ‹service› находятся вне тега ‹application› в AndroidManifest.xml Здесь я готов ответить stackoverflow.com/a/37352142/6366150 - person Gonzalo; 24.05.2016
comment
Работает только с запущенным приложением переднего плана ... в фоновом режиме все еще сохраняет прежнее поведение - person Gonzalo; 24.05.2016
comment
когда приложение находится на переднем плане, этот значок пользовательского уведомления появляется и работает нормально, но в фоновом режиме приложения появляется белый квадратный значок, пожалуйста, помогите мне - person Harsha; 24.11.2016

напиши это

<meta-data 
         android:name="com.google.firebase.messaging.default_notification_icon"
         android:resource="@drawable/ic_notification" />

вправо вниз <application.....>

введите здесь описание изображения

person dmarquina    schedule 11.06.2019

Думал, что добавлю ответ на этот вопрос, так как моя проблема была простой, но ее трудно было заметить. В частности, я скопировал / вставил существующий элемент метаданных при создании моего com.google.firebase.messaging.default_notification_icon, который использовал тег android:value для указания его значения. Это не сработает для значка уведомления, и как только я изменил его на android:resource, все заработало, как ожидалось.

person Charles A.    schedule 13.06.2019
comment
То же самое и с метой default_notification_color, это должно быть android:resource - настройка, поскольку android:value не будет работать - person flochtililoch; 14.01.2020