web-dev-qa-db-fra.com

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é cette nouvelle FCM (Firebase Cloud Messaging) avec l'exemple sur Github.

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

Pourquoi ? Ci-dessous le code officiel de traitement du 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());
    }

}
113
marco

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 appropriée Android) pour les messages envoyés à partir de la console.

Avec 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 entièrement 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.

233
Ian Barber

Utilisez une implémentation de serveur pour envoyer des messages à votre client et utilisez data type de messages plutôt que notification type de messages.

Cela vous aidera à obtenir un rappel sur onMessageReceived, que votre application soit en arrière-plan ou à l'avant-plan et vous pourrez alors générer votre notification personnalisée.

33
geekoraul

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

lorsque vous envoyez une notification à partir de la console Firebase, l’icône de votre application est utilisée par défaut. Le système Android devient blanc lorsque cette icône est affichée 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 le seul moyen.

edit: avec 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
Jan Hartwig

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 l'intention (qui est publique, au moins dans la version 9.6.1) et extraire les informations à afficher des extras. La partie "hacky" est que le nom de la méthode est effectivement obscurci et va changer chaque fois que vous mettez à jour le sdk de Firebase vers une nouvelle version, mais vous pouvez le rechercher rapidement en inspectant FirebaseMessagingService avec Android Studio et en recherchant pour une méthode publique qui prend 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());
    }
}
6
Carlo Conserva

Il y a aussi un chemin moche mais efficace. Décompilez FirebaseMessagingService.class et modifiez son comportement. Ensuite, placez simplement la classe dans le bon paquet dans votre application et dex l’utilise au lieu de la classe dans la bibliothèque de messagerie elle-même. C'est assez facile et ça marche.

Il y a 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 est à partir de la version 9.4.0, la méthode aura différents noms dans différentes versions en raison de l'obscurcissement.

3
ATom

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

3
rattisuk

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

enter image description here

2
brook

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:

Notification capture d'écran

À la place de mon icône personnalisée dans le code (setSmallIcon ou setSmallIcon) ou une 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);
    }
2
Gonzalo

écrire cela

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

tout en bas <application.....>

enter image description here

1
dmarquina

J'ai pensé ajouter une réponse à celle-ci, car mon problème était simple mais difficile à remarquer. En particulier, j'avais copié/collé un élément de métadonnées existant lors de la création de mon com.google.firebase.messaging.default_notification_icon, qui utilisait une balise Android:value pour spécifier sa valeur. Cela ne fonctionnera pas pour l'icône de notification, et une fois que je l'ai changé en Android:resource tout a fonctionné comme prévu.

0
Charles A.