Question Icône de notification avec le nouveau système de messagerie Firebase Cloud


Hier, Google a présenté à Google I / O le nouveau système de notification basé sur la nouvelle Firebase. J'ai essayé ce nouveau FCM (Firebase Cloud Messaging) avec l'exemple de Github.

L'icône de la notification est toujours la ic_launcher malgré que j'ai déclaré un dessinable spécifique

Pourquoi ? Ci-dessous le code officiel pour gérer le message

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());
    }

}

84
2018-05-19 13:41


origine


Réponses:


Malheureusement, il s'agissait d'une limitation des notifications Firebase dans SDK 9.0.0-9.6.1. Lorsque l'application est en arrière-plan, l'icône du lanceur est utilisée à partir du manifeste (avec la teinte Android requise) pour les messages envoyés depuis la console.

Avec le SDK 9.8.0, vous pouvez toutefois remplacer la valeur par défaut! Dans votre fichier AndroidManifest.xml, vous pouvez définir les champs suivants pour personnaliser l'icône et la couleur:

<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" />

Notez que si l'application est au premier plan (ou qu'un message de données est envoyé), vous pouvez utiliser votre propre logique pour personnaliser l'affichage. Vous pouvez également toujours personnaliser l'icône si vous envoyez le message à partir des API HTTP / XMPP.


185
2018-05-19 19:34



Utiliser une implémentation de serveur pour envoyer des messages à votre client et utiliser Les données type de messages plutôt que notification type de messages.

Cela vous aidera à obtenir un rappel pour onMessageReceived peu importe si votre application est en arrière-plan ou au premier plan et que vous pouvez générer votre notification personnalisée,


23
2018-05-27 18:19



En solution courte

Cela se produit uniquement lors de l'envoi de messages via la console de Firebase et non par l'API

Problème

Passage de l'ancien gcm au nouveau FirebaseMessagingService Je pensais qu'il serait bon de tester donc j'ai créé des messages en utilisant la console firebase et j'ai constaté que lorsque l'app est en arrière-plan, ma notification personnalisée ne fonctionnait pas et Firebase onMessageReceived

Solution

J'ai essayé de créer des messages à partir de l'API et seulement à ce moment-là, j'ai réalisé que FireMase onMessageReceived n'était pas appelé lorsque l'application en arrière-plan se produisait uniquement lors de la création de messages depuis la console Firebase.


10
2018-05-21 15:52



atm ils travaillent sur cette question https://github.com/firebase/quickstart-android/issues/4

Lorsque vous envoyez une notification à partir de la console Firebase, vous utilisez par défaut l'icône de l'application et le système Android devient blanc lorsque vous vous trouvez dans la barre de notification.

Si vous n'êtes pas satisfait de ce résultat, vous devez implémenter FirebaseMessagingService et créer les notifications manuellement lorsque vous recevez un message. Nous travaillons sur un moyen d'améliorer cela, mais pour l'instant, c'est la seule façon.

edit: avec le SDK 9.8.0, ajouter à AndroidManifest.xml

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

7
2018-05-26 13:57



Ma solution est similaire à celle d'ATom, mais plus facile à mettre en œuvre. Vous n'avez pas besoin de créer une classe qui occulte complètement FirebaseMessagingService, vous pouvez simplement remplacer la méthode qui reçoit Intent (qui est publique, au moins dans la version 9.6.1) et prendre les informations à afficher des extras. La partie "hacky" est que le nom de la méthode est en effet obscurci et va changer à chaque fois que vous mettez à jour le sdk Firebase vers une nouvelle version, mais vous pouvez le rechercher rapidement en inspectant FirebaseMessagingService avec Android Studio. une Intention comme seul paramètre. Dans la version 9.6.1, il s'appelle zzm. Voici à quoi ressemble mon service:

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());
    }
}

5
2017-10-17 15:26



Il y a aussi une manière moche mais efficace. Décompiler FirebaseMessagingService.class et modifier son comportement. Ensuite, placez simplement la classe dans le bon package dans yout app et utilisez-la à la place de la classe dans la lib de messagerie elle-même. C'est assez simple et efficace.

Il y a une méthode:

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));
}

Ce code provient de la version 9.4.0, la méthode aura des noms différents dans des versions différentes en raison de l'obscurcissement.


3
2017-09-04 18:46



Il suffit de définir targetSdkVersion sur 19. L'icône de notification sera colorée. Attendez ensuite que Firebase répare ce problème.


2
2018-06-20 17:55



si votre application est en arrière-plan, l'icône de notification sera définie sur la méthode de réception onMessage, mais si votre application est en avant-plan, l'icône de notification sera celle que vous avez définie sur le manifeste.

enter image description here


2
2017-12-16 13:24



Je déclenche mes notifications depuis la console FCM et via HTTP / JSON ... avec le même résultat.

Je peux gérer le titre, le message complet, mais l'icône est toujours un cercle blanc par défaut:

Capture d'écran de notification

Au lieu de mon icône personnalisée dans le code (setSmallIcon ou setSmallIcon) ou l'icône par défaut de l'application:

 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);
    }

1
2018-05-22 00:55