Ikon Pemberitahuan dengan sistem Firebase Cloud Messaging baru

132

Kemarin Google mempresentasikan di Google I / O sistem notifikasi baru berdasarkan Firebase baru. Saya mencoba FCM baru ini (Firebase Cloud Messaging) dengan contoh di Github.

Ikon notifikasi selalu ic_launcher meskipun saya telah menyatakan drawable spesifik

Mengapa Di sini di bawah kode resmi untuk menangani pesan

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

}
marco
sumber
firebase tidak ada hubungannya dengan bagaimana ANDA membuat pemberitahuan, berikan gambar seperti apa yang Anda lihat
tyczj
1
tepat. kode ini berasal langsung dari Firebase dan metode sendNotification () persis sama untuk setiap notifikasi. Kode ini berfungsi baik dengan GCM, tetapi dengan FCM no. selalu tetap ic_launcher, menggunakan antarmuka web baru untuk mengirim pesan
marco
Anda mengatur ikon kecil tetapi bukan ikon besar, kecuali jika Anda mengirim push dengan tag notifikasi di payload push itu tidak ada hubungannya dengan FCM
tyczj
Apakah itu menampilkan ikon notifikasi khusus Anda ketika aplikasi di latar depan? Itu bekerja untuk saya. Namun, ketika aplikasi berada di latar belakang, ia harus menggunakan semacam pengendali FCM default, karena semua pengaturan notifikasi diabaikan (ikon, suara, lampu, getar, dll. Tidak dapat dikustomisasi).
shinypenguin

Jawaban:

267

Sayangnya ini adalah batasan Notifikasi Firebase di SDK 9.0.0-9.6.1. Ketika aplikasi di latar belakang ikon peluncur digunakan dari manifes (dengan pewarnaan Android yang diperlukan) untuk pesan yang dikirim dari konsol.

Namun dengan SDK 9.8.0, Anda dapat mengganti default! Di AndroidManifest.xml Anda, Anda dapat mengatur bidang-bidang berikut untuk menyesuaikan ikon dan warna:

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

Perhatikan bahwa jika aplikasi berada di latar depan (atau pesan data dikirim), Anda dapat sepenuhnya menggunakan logika Anda sendiri untuk menyesuaikan tampilan. Anda juga dapat selalu menyesuaikan ikon jika mengirim pesan dari HTTP / XMPP APIs.

Ian Barber
sumber
1
@Ian Barber: ada rencana di Google untuk mengubah perilaku ini dalam waktu dekat?
skylve
1
Tim menyadari masalah ini dan sedang mengerjakan perbaikan.
Arthur Thompson
1
ada pembaruan tentang ini? pikir saya akan bertanya karena ada keadaan ketika seorang insinyur Google hanya lupa untuk mendorong tambalan.
CQM
7
Ah, saya bisa menggunakannya dengan 9.8.0. Untuk membantu orang lain, ingat ikon bilah status Anda harus memenuhi persyaratan: developer.android.com/guide/practices/ui_guidelines/… . Milik saya tidak dan karena itu firebase hanya default ke whitesquare standar daripada menggunakan ikon yang ditentukan dalam manifes.
zaifrun
3
Jika Anda kebetulan mencoba ini dan menemukan bahwa ikon lebih kecil dari notifikasi lainnya, pastikan Anda menggunakan vektor yang dapat digambar (dan bukan png). Itu menyelesaikannya untuk saya.
riper
35

Gunakan implementasi server untuk mengirim pesan ke klien Anda dan menggunakan tipe data pesan, bukan tipe pemberitahuan pesan.

Ini akan membantu Anda menerima panggilan balik onMessageReceivedterlepas dari apakah aplikasi Anda di latar belakang atau latar depan dan Anda dapat menghasilkan notifikasi khusus Anda kemudian

geekoraul
sumber
2
Ini adalah solusi yang disarankan dalam dokumen Firebase juga, Anda dapat menampilkan pemberitahuan dengan cara apa pun yang Anda sukai jika Anda mengandalkan dorongan data alih-alih pemberitahuan.
ras
1
ya setuju. ini harus ditandai sebagai jawaban yang benar. atau jawaban saya di bawah ini :)
Developine
3
Tidak, itu tidak layak untuk orang-orang yang perlu menjaga kompatibilitas dengan klien lain / versi lama yang mengharapkan pemberitahuan.
Gabor
Kami memiliki aplikasi dalam produksi yang sudah mengharapkan jenis pemberitahuan push dan kami telah memperluas komponen backend (kompleks) untuk menambahkan data untuk klien baru. Tetapi kami tidak dapat menghapus dukungan untuk versi lawas aplikasi kami.
Gabor
Oh saya setuju. Itu masalah lain. Saya menyarankan untuk membaca dokumen secara menyeluruh sebelum mengintegrasikan. Juga untuk menguji secara menyeluruh sebelum melepaskan ke produksi. Masalahnya bisa dihindari jika aplikasi diuji dengan baik sebelum diluncurkan. Bagaimanapun, Anda memiliki sesuatu untuk dipelajari.
geekoraul
9

atm mereka sedang mengerjakan masalah itu https://github.com/firebase/quickstart-android/issues/4

saat Anda mengirim pemberitahuan dari Firebase console menggunakan ikon aplikasi Anda secara default, dan sistem Android akan mengubah ikon itu menjadi putih pekat saat berada di bilah notifikasi.

Jika Anda tidak puas dengan hasil itu, Anda harus mengimplementasikan FirebaseMessagingService dan membuat notifikasi secara manual ketika Anda menerima pesan. Kami sedang berupaya untuk meningkatkan ini tetapi untuk saat ini itulah satu-satunya cara.

sunting: dengan SDK 9.8.0 tambahkan ke AndroidManifest.xml

<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/my_favorite_pic"/>
Jan Hartwig
sumber
cara menampilkan baki notifikasi ikon yang disesuaikan di marshmallow
Harsha
6

Solusi saya mirip dengan ATom, tetapi lebih mudah diimplementasikan. Anda tidak perlu membuat kelas yang membayangi FirebaseMessagingService sepenuhnya, Anda bisa mengganti metode yang menerima Intent (yang bersifat publik, setidaknya dalam versi 9.6.1) dan mengambil informasi yang akan ditampilkan dari ekstra. Bagian "peretasan" adalah bahwa nama metode memang dikaburkan dan akan berubah setiap kali Anda memperbarui Firebase SDK ke versi baru, tetapi Anda dapat mencarinya dengan cepat dengan memeriksa FirebaseMessagingService dengan Android Studio dan mencari metode publik yang membutuhkan Intent sebagai satu-satunya parameter. Dalam versi 9.6.1 itu disebut zzm. Begini tampilannya layanan saya:

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());
    }
}
Carlo Conserva
sumber
gcm.notification.title untuk nama kunci 100% aman untuk semua versi?
pedroooo
3

Cukup atur targetSdkVersion ke 19. Ikon pemberitahuan akan berwarna. Lalu tunggu Firebase untuk memperbaiki masalah ini.

rattisuk
sumber
7
: D Wow, jadi di mana daftar efek sampingnya?
Eugen Pechanec
@EugenPechanec ya, manfaatnya adalah Anda mungkin tidak dapat menggunakan beberapa API yang tersedia di 20+
benleung
3

Ada juga satu cara jelek tapi berfungsi. Dekompilasi FirebaseMessagingService.class dan modifikasi perilaku itu. Kemudian letakkan kelas ke paket yang tepat di aplikasi Anda dan gunakan itu bukan kelas di lib perpesanan itu sendiri. Cukup mudah dan berfungsi.

Ada metode:

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

Kode ini berasal dari versi 9.4.0, metode akan memiliki nama yang berbeda di versi yang berbeda karena kebingungan.

Atom
sumber
3

jika aplikasi Anda di latar belakang ikon pemberitahuan akan ditetapkan pada metode Penerimaan pesan tetapi jika aplikasi Anda di latar depan ikon pemberitahuan akan menjadi yang Anda tetapkan pada manifes

masukkan deskripsi gambar di sini

anak sungai
sumber
2

Saya memicu pemberitahuan dari konsol FCM dan melalui HTTP / JSON ... dengan hasil yang sama.

Saya dapat menangani judul, pesan lengkap, tetapi ikon selalu merupakan lingkaran putih default:

Tangkapan layar pemberitahuan

Alih-alih ikon kustom saya dalam kode (setSmallIcon atau setSmallIcon) atau ikon default dari aplikasi:

 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);
    }
Gonzalo
sumber
1
Mengerti! tag <service> saya kehabisan tag <aplikasi> di AndroidManifest.xml Di sini saya mencari jawabannya stackoverflow.com/a/37352142/6366150
Gonzalo
Hanya berfungsi dengan aplikasi latar depan berjalan ... di latar belakang masih mendapatkan perilaku yang sama sebelumnya
Gonzalo
ketika aplikasi di forground yang ikon pemberitahuan pelanggan datang dan berfungsi dengan baik tetapi di latar belakang aplikasi mendapatkan ikon kotak putih tolong bantu saya
Harsha
1

tulis ini

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

kanan bawah <application.....>

masukkan deskripsi gambar di sini

dmarquina
sumber
0

Saya pikir saya akan menambahkan jawaban untuk yang ini, karena masalah saya sederhana tetapi sulit untuk diketahui. Khususnya saya telah menyalin / menempel elemen meta-data yang ada saat membuat saya com.google.firebase.messaging.default_notification_icon, yang menggunakan android:valuetag untuk menentukan nilainya. Ini tidak akan berfungsi untuk ikon notifikasi, dan begitu saya mengubahnya ke android:resourcesemuanya berfungsi seperti yang diharapkan.

Charles A.
sumber
Sama berlaku untuk default_notification_colormeta, itu harus android:resource- pengaturan karena android:valuetidak akan berfungsi
flochtililoch