Firebase onMessageReceived tidak dipanggil saat aplikasi di latar belakang

233

Saya bekerja dengan Firebase dan menguji pengiriman pemberitahuan ke aplikasi saya dari server saya saat aplikasi di latar belakang. Pemberitahuan berhasil dikirim, bahkan muncul di pusat notifikasi perangkat, tetapi ketika pemberitahuan muncul atau bahkan jika saya mengkliknya, metode onMessageReceived di dalam FCMessagingService saya tidak pernah dipanggil.

Ketika saya menguji ini ketika aplikasi saya berada di latar depan, metode onMessageReceived dipanggil dan semuanya bekerja dengan baik. Masalahnya terjadi ketika aplikasi berjalan di latar belakang.

Apakah ini perilaku yang dimaksudkan, atau adakah cara saya bisa memperbaikinya?

Inilah FBMessagingService saya:

import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class FBMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.i("PVL", "MESSAGE RECEIVED!!");
        if (remoteMessage.getNotification().getBody() != null) {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody());
        } else {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message"));
        }
    }
}
Cyogenos
sumber
Selain json body, di mana kode onTokenRefresh Anda ? Sudahkah Anda menyelesaikan pengaturan Android ?
Kato
4
Apa maksud Anda json body dari notifikasi? Juga, kode onTokenRefresh saya ada di dalam layanan FirebaseInstanceID saya.
Cyogenos
Bisakah Anda memposting payload sampel yang Anda kirim?
AL.
Anda juga dapat memeriksa utas ini stackoverflow.com/questions/39046270/…
Md. Sajedul Karim

Jawaban:

144

Ini berfungsi sebagaimana mestinya, pesan pemberitahuan dikirim ke panggilan balik onMessageReceived Anda hanya ketika aplikasi Anda di latar depan. Jika aplikasi Anda berada di latar belakang atau ditutup maka pesan pemberitahuan ditampilkan di pusat pemberitahuan, dan data apa pun dari pesan itu diteruskan ke maksud yang diluncurkan sebagai hasil dari pengguna mengetuk pemberitahuan tersebut.

Anda dapat menentukan click_action untuk menunjukkan niat yang harus diluncurkan ketika pemberitahuan diketuk oleh pengguna. Aktivitas utama digunakan jika tidak ada click_action yang ditentukan.

Saat niat diluncurkan, Anda dapat menggunakan

getIntent().getExtras();

untuk mengambil Set yang akan menyertakan data yang dikirim bersama dengan pesan notifikasi.

Untuk lebih lanjut tentang pesan pemberitahuan, lihat dokumen .

Arthur Thompson
sumber
6
Apakah ada cara untuk mengatur click_actionkapan saya menggunakan Firebase Notification Console?
Nii Laryea
6
ok, tapi bagaimana jika aplikasi ini terbunuh (tidak ada latar depan atau latar belakang)?
michalu
3
Tetapi bagaimana cara menonaktifkan notifikasi membuang pengguna? Karena jika pengguna membuangnya, itu berarti semua data akan dilewati ... Benar?
Aleksey Timoshchenko
4
Benar! Jadi saat mengirim pesan notifikasi ke Android, data yang menyertainya harus berupa data yang meningkatkan pengalaman notifikasi. Seharusnya bukan data penting aplikasi, gunakan pesan data untuk data yang dibutuhkan aplikasi bahkan jika pengguna menolak pemberitahuan.
Arthur Thompson
3
Ini tidak sepenuhnya benar. Jika pesan tidak hanya berisi data dan bukan muatan notifikasi, pesan akan SELALU dikirim ke onMessageReceive, jika aplikasi berada di latar depan atau tidak.
JacksOnF1re
125

Hapus notificationbidang sepenuhnya dari permintaan server Anda. Kirim sajadata dan tangani onMessageReceived()jika tidak, Anda onMessageReceived()tidak akan dipicu ketika aplikasi di latar belakang atau terbunuh.

Jangan lupa untuk memasukkan "priority": "high"bidang dalam permintaan pemberitahuan Anda. Menurut dokumentasi: pesan data dikirim dengan prioritas normal, sehingga mereka tidak akan tiba secara instan; bisa juga itu masalahnya.

Inilah yang saya kirim dari server

{
  "data":{
    "id": 1,
    "missedRequests": 5
    "addAnyDataHere": 123
  },
  "to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......",
  "priority": "high"
}

Jadi Anda dapat menerima data Anda onMessageReceived(RemoteMessage message)seperti ini .... katakanlah saya harus mendapatkan id

Object obj = message.getData().get("id");
        if (obj != null) {
            int id = Integer.valueOf(obj.toString());
        }
Zohab Ali
sumber
9
Saya menemukan bahwa jika saya hanya mengirim pesan data, Maka Aplikasi yang dihapus dari task manager tidak akan bisa mendapatkan notifikasi. Apakah ini perilaku yang dimaksudkan?
Prabhjot Singh
2
Ini adalah solusi bagi saya untuk menerima pesan di latar belakang!
Ray Hulha
5
Di Oreo ketika aplikasi terbunuh, onMessageReceived tidak dipanggil. saya hanya punya payload dengan data saja. Apakah ada pembaruan yang Anda miliki?
Samir Mangroliya
2
Bekerja seperti pesona!
ssk
3
Love you alot for this answer: p
Ahmad Arslan
63

metode ini handleIntent () telah didepresiasi, jadi penanganan notifikasi dapat dilakukan seperti di bawah ini:

  1. Status Latar Depan: Klik notifikasi akan menuju ke aktivitas Intent yang tertunda yang Anda sediakan saat membuat notifikasi pro-gramatikal seperti yang umumnya dibuat dengan muatan data notifikasi.

  2. Latar Belakang / Status Terbunuh - Di sini, sistem itu sendiri membuat notifikasi berdasarkan muatan notifikasi dan mengklik notifikasi itu akan membawa Anda ke aktivitas peluncur aplikasi tempat Anda dapat dengan mudah mengambil data Intent dalam salah satu metode siklus hidup Anda.

manas.abrol
sumber
Terima kasih!!! Saya kehilangan beberapa hari karena masalah ini dan ini menyelamatkan saya.
Igor Janković
benar-benar solusi sempurna!
EduXavier
4
Saya menangani logika tampilan notifikasi di handleIntent (Intent intent), namun ketika aplikasi di latar belakang, 2 notifikasi ditampilkan, satu notifikasi yang saya buat dan lainnya secara default yang berisi seluruh pesan dari notifikasi.
Joyson
5
Luar biasa, tapi saya tidak melihat ada gunanya OnMessageReceiveddalam kasus ini!?
Alaa AbuZarifa
8
Saya memiliki com.google.firebase: firebase-messaging: 11.6.2 & handleIntent sudah final sekarang.Periksa stackoverflow.com/questions/47308155/…
Ronak Poriya
31

Berikut adalah konsep yang lebih jelas tentang pesan firebase. Saya menemukannya dari tim dukungan mereka.

Firebase memiliki tiga jenis pesan :

Pesan pemberitahuan : Pesan pemberitahuan berfungsi di latar belakang atau latar depan. Saat aplikasi di latar belakang, pesan pemberitahuan dikirim ke baki sistem. Jika aplikasi di latar depan, pesan akan ditangani oleh onMessageReceived()atau didReceiveRemoteNotificationdipanggil kembali. Ini pada dasarnya adalah apa yang disebut sebagai pesan tampilan.

Pesan data : Pada platform Android, pesan data dapat bekerja di latar belakang dan latar depan. Pesan data akan ditangani oleh onMessageReceived (). Catatan khusus platform di sini adalah: Di Android, muatan data dapat diambil di Intent yang digunakan untuk meluncurkan aktivitas Anda. Untuk menguraikan, jika sudah "click_action":"launch_Activity_1", Anda dapat mengambil maksud ini getIntent()hanya dari Activity_1.

Pesan dengan notifikasi dan muatan data : Ketika di latar belakang, aplikasi menerima muatan notifikasi di baki notifikasi, dan hanya menangani muatan data ketika pengguna mengetuk notifikasi. Saat berada di latar depan, aplikasi Anda menerima objek pesan dengan kedua payload tersedia. Kedua, parameter click_action sering digunakan dalam muatan notifikasi dan bukan dalam muatan data. Jika digunakan di dalam payload data, parameter ini akan diperlakukan sebagai pasangan nilai kunci khusus dan oleh karena itu Anda perlu menerapkan logika khusus agar berfungsi sesuai yang diinginkan.

Juga, saya sarankan Anda untuk menggunakan metode onMessageReceived (lihat Pesan data) untuk mengekstrak bundel data. Dari logika Anda, saya memeriksa objek bundel dan belum menemukan konten data yang diharapkan. Berikut ini adalah referensi untuk kasus serupa yang mungkin memberikan lebih banyak kejelasan.

Dari sisi server, pemberitahuan firebase harus di bawah format :

Sisi server harus mengirim objek "pemberitahuan" . Kurangnya objek "pemberitahuan" di saya TargetActivitytidak mendapatkan pesan menggunakan getIntent().

Format pesan yang benar diberikan di bawah ini:

{
 "data": {
  "body": "here is body",
  "title": "Title"
 },
"notification": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
 "to": "ffEseX6vwcM:APA91bF8m7wOF MY FCM ID 07j1aPUb"
}

Berikut adalah konsep yang lebih jelas tentang pesan firebase. Saya menemukannya dari tim dukungan mereka.

Untuk info lebih lanjut, kunjungi utas saya dan utas ini

Md. Sajedul Karim
sumber
3
layak disebutkan bahwa "pesan data" tidak akan diterima jika perangkat dalam mode tertidur dalam (diperkenalkan di Android 7.0). hati-hati dengan itu!
Sameer J
30

Saya memiliki masalah yang sama. Lebih mudah menggunakan 'pesan data' daripada 'notifikasi'. Pesan data selalu memuat kelas onMessageReceived.

Di kelas itu Anda dapat membuat notifikasi sendiri dengan pembuat notifikasi.

Contoh:

 @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
    }

    private void sendNotification(String messageTitle,String messageBody) {
        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_UPDATE_CURRENT);

        long[] pattern = {500,500,500,500,500};

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

        NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setVibrate(pattern)
                .setLights(Color.BLUE,1,1)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
Koot
sumber
7
Terima kasih .. Saya mengubah kode server saya dan menggunakan "data" alih-alih "pemberitahuan" dan sekarang berfungsi dengan baik,
Mahesh Kavathiya
5
@Koot itu berfungsi hanya jika aplikasi di latar depan tidak jika di latar belakang. dapatkah kamu membantu saya untuk memicu acara ini dalam kedua kasus ??
Anant Shah
@AnantShah bagaimana POST Anda ke server Firebase terlihat?
Koot
3
Sebenarnya ada tiga kemungkinan kasus di sini. 1) Aplikasi di latar depan. 2) Aplikasi di latar belakang. 3) Aplikasi tidak berjalan. Seperti yang Anda katakan, pesan 'data' akan diterima dalam dua kasus pertama, tetapi tidak dalam kasus ketiga, ketika aplikasi tidak berjalan. Untuk memenuhi ketiga kasus tersebut, Anda perlu mengatur bidang 'pemberitahuan' dalam pesan. (Juga ide yang bagus jika Anda ingin mendukung iOS dan juga klien Android)
Steve Moseley
1
Bahkan dalam aplikasi tidak berjalan, saya masih mendapatkan pesan dari server pada fungsi yang saya terima. Saya setuju dengan Anda bahwa lebih baik menggunakan 'notifikasi' jika Anda ingin mendukung ios juga.
Koot
21

Sesuai dokumentasi Firebase Cloud Messaging-Jika Kegiatan di latar depan maka onMessageReceived akan dipanggil. Jika Kegiatan di latar belakang atau tertutup maka pesan pemberitahuan ditampilkan di pusat pemberitahuan untuk aktivitas peluncur aplikasi. Anda dapat memanggil aktivitas khusus Anda dengan mengklik pemberitahuan jika aplikasi Anda ada di latar belakang dengan memanggil api layanan sisanya untuk pesan berbasis firebase sebagai:

URL- https://fcm.googleapis.com/fcm/send

Jenis Metode - POST

Header- Content-Type:application/json
Authorization:key=your api key

Tubuh / Muatan:

{ "notification": {
    "title": "Your Title",
    "text": "Your Text",
     "click_action": "OPEN_ACTIVITY_1" // should match to your intent filter
  },
    "data": {
    "keyname": "any value " //you can get this data as extras in your activity and this data is optional
    },
  "to" : "to_id(firebase refreshedToken)"
} 

Dan dengan ini di aplikasi Anda, Anda dapat menambahkan kode di bawah ini dalam aktivitas Anda untuk dipanggil:

<intent-filter>
                <action android:name="OPEN_ACTIVITY_1" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
Ankit Adlakha
sumber
Di mana saya akan membuat niat dan minta dia membuka kegiatan tertentu? Saya tahu ini mendaftarkan maksud OPEN_ACTIVITY_1 dalam manifes, tetapi di mana sebenarnya saya menyebutnya?
Cyogenos
Haruskah kita memanggil aktivitas dari filter maksud? Atau mulai secara manual onMessageReceived?
CoolMind
14

Metode onMessageReceived (RemoteMessage remoteMessage) dipanggil berdasarkan kasus-kasus berikut.

  • Tanggapan FCM Dengan pemberitahuan dan blok data :
{
  
"to": "device token list",
  "notification": {
    "body": "Body of Your Notification",
    "title": "Title of Your Notification"
  },
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}
  1. Aplikasi di Latar Depan:

onMessageReceived (RemoteMessage remoteMessage) disebut, menampilkan LargeIcon dan BigPicture di bilah notifikasi. Kita dapat membaca konten dari notifikasi dan blok data

  1. Aplikasi di Latar Belakang:

onMessageReceived (RemoteMessage remoteMessage) tidak dipanggil, system tray akan menerima pesan dan membaca isi dan judul dari blok notifikasi dan menampilkan pesan dan judul default di bilah notifikasi.

  • Tanggapan FCM Dengan hanya blok data :

Dalam hal ini, menghapus blok notifikasi dari json

{
  
"to": "device token list",
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}

Solusi untuk memanggil onMessageReceived ()

  1. Aplikasi di Latar Depan:

onMessageReceived (RemoteMessage remoteMessage) disebut, menampilkan LargeIcon dan BigPicture di bilah notifikasi. Kita dapat membaca konten dari notifikasi dan blok data

  1. Aplikasi di Latar Belakang:

onMessageReceived (RemoteMessage remoteMessage) disebut, system tray tidak akan menerima pesan karena kunci notifikasi tidak ada dalam respons. Memperlihatkan LargeIcon dan BigPicture di bilah notifikasi

Kode

 private void sendNotification(Bitmap bitmap,  String title, String 
    message, PendingIntent resultPendingIntent) {

    NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
    style.bigPicture(bitmap);

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

    NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    String NOTIFICATION_CHANNEL_ID = mContext.getString(R.string.default_notification_channel_id);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);

        notificationManager.createNotificationChannel(notificationChannel);
    }
    Bitmap iconLarge = BitmapFactory.decodeResource(mContext.getResources(),
            R.drawable.mdmlogo);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.mdmlogo)
            .setContentTitle(title)
            .setAutoCancel(true)
            .setSound(defaultSound)
            .setContentText(message)
            .setContentIntent(resultPendingIntent)
            .setStyle(style)
            .setLargeIcon(iconLarge)
            .setWhen(System.currentTimeMillis())
            .setPriority(Notification.PRIORITY_MAX)
            .setChannelId(NOTIFICATION_CHANNEL_ID);


    notificationManager.notify(1, notificationBuilder.build());


}

Tautan Referensi:

https://firebase.google.com/docs/cloud-messaging/android/receive

vishnuc156
sumber
Bagian terpenting bagi orang yang menderita masalah latar belakang adalah menghapus properti "pemberitahuan" dari JSON yang dikirim oleh server. ini menyelesaikan masalah. Terima kasih banyak.
Ramy M. Mousa
13

Saya mendapat masalah yang sama. Jika aplikasi ini foreground - memicu layanan latar belakang saya di mana saya dapat memperbarui database saya berdasarkan jenis notifikasi. Tapi, aplikasi pergi ke latar belakang - layanan notifikasi default akan berhati-hati untuk menunjukkan notifikasi kepada pengguna.

Inilah solusi saya untuk mengidentifikasi aplikasi di latar belakang dan memicu layanan latar belakang Anda,

public class FirebaseBackgroundService extends WakefulBroadcastReceiver {

  private static final String TAG = "FirebaseService";

  @Override
  public void onReceive(Context context, Intent intent) {
    Log.d(TAG, "I'm in!!!");

    if (intent.getExtras() != null) {
      for (String key : intent.getExtras().keySet()) {
        Object value = intent.getExtras().get(key);
        Log.e("FirebaseDataReceiver", "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("gcm.notification.body") && value != null) {
          Bundle bundle = new Bundle();
          Intent backgroundIntent = new Intent(context, BackgroundSyncJobService.class);
          bundle.putString("push_message", value + "");
          backgroundIntent.putExtras(bundle);
          context.startService(backgroundIntent);
        }
      }
    }
  }
}

Di manifes.xml

<receiver android:exported="true" android:name=".FirebaseBackgroundService" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </receiver>

Menguji solusi ini dalam versi android 8.0 terbaru. Terima kasih

Nagendra Badiganti
sumber
bagaimana menggunakan kelas FirebaseBackgroundService ini ?? @Nagendra Badiganti
di mana menggunakan kode ini kelas publik FirebaseBackgroundService extends WakefulBroadcastReceiver @Nagendra Badiganti
buat kelas layanan di paket Anda dan daftar di manifes.xml Anda. Pastikan Anda memiliki filter untuk notifikasi. Karena layanan memicu untuk setiap notifikasi GCM.
Nagendra Badiganti
firebase.google.com/docs/cloud-messaging/android/… saya mengikuti tautan ini, saya perlu menambahkan kelas ini untuk menerima pemberitahuan. hanya mengirim pesan dari firebase pesan pertama .. dikatakan sudah selesai tetapi tidak menerima notifikasi @Nagendra Badiganti
1
WakefulBroadcastReceivertidak digunakan lagi sejak API level 26.1.0.
Minoru
12

Jika aplikasi dalam modus latar belakang atau tidak aktif (dibunuh), dan Anda klik pada Pemberitahuan , Anda harus memeriksa muatan di LaunchScreen (di saya layar kasus peluncuran adalah MainActivity.java).

Jadi di MainActivity.java pada onCreate periksa Ekstra :

    if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Log.d("MainActivity: ", "Key: " + key + " Value: " + value);
        }
    }
Gent Berani
sumber
Bagaimana saya bisa mendapatkan judul, tubuh, dan data notifikasi?
Md.Tarikul Islam
1
Terima kasih, ini jawabannya. @ Md.Tarikul Islam menggunakan onMessageReceived () seperti yang disebutkan dalam pertanyaan ini.
felixwcf
7

Timpa handleIntentMetode FirebaseMessageServicekarya untuk saya.

di sini kode dalam C # (Xamarin)

public override void HandleIntent(Intent intent)
{
    try
    {
        if (intent.Extras != null)
        {
            var builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            foreach (string key in intent.Extras.KeySet())
            {
                builder.AddData(key, intent.Extras.Get(key).ToString());
            }

            this.OnMessageReceived(builder.Build());
        }
        else
        {
            base.HandleIntent(intent);
        }
    }
    catch (Exception)
    {
        base.HandleIntent(intent);
    }
}

dan itulah Kode di Jawa

public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }

            onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}
t3h Exi
sumber
handleIntent () adalah final
Ettore
@ Ettore Bagaimana saya bisa memanggil fungsi handleIntent?
Hiroto
Metode ini dipanggil ketika Anda menerima pesan dari Firebase, tetapi Anda tidak dapat menimpa karena metode ini dinyatakan final. (Firebase 11.6.0)
Ettore
5

Secara default Aktivitas Peluncur di aplikasi Anda akan diluncurkan ketika aplikasi Anda di latar belakang dan Anda mengklik pemberitahuan, jika Anda memiliki bagian data dengan pemberitahuan Anda, Anda dapat menanganinya dalam aktivitas yang sama seperti berikut,

if(getIntent().getExtras()! = null){
  //do your stuff
}else{
  //do that you normally do
}
Uzair
sumber
Jika saya menavigasi dari mainActivity, bagaimana menavigasi kembali ke Kegiatan tertentu akan bekerja?
Mac_Play
@Uzair getIntent (). GetExtras () selalu mendapatkan null, Apakah Anda punya solusi lain? Saat aplikasi bacground onMessageReceived metode tidak menelepon
user2025187
3

Jika aplikasi berada di latar belakang Fire-base secara default menangani notifikasi Tetapi jika kita ingin notifikasi custom kita daripada kita harus mengubah sisi server kita, yang bertanggung jawab untuk mengirim data kustom kita (payload data)

Hapus muatan notifikasi sepenuhnya dari permintaan server Anda. Kirim hanya Data dan tangani di onMessageReceived () jika tidak onMessageReceived Anda tidak akan terpicu ketika aplikasi di latar belakang atau dibunuh.

sekarang, format kode sisi server Anda terlihat seperti,

{
  "collapse_key": "CHAT_MESSAGE_CONTACT",
  "data": {
    "loc_key": "CHAT_MESSAGE_CONTACT",
    "loc_args": ["John Doe", "Contact Exchange"],
    "text": "John Doe shared a contact in the group Contact Exchange",
    "custom": {
      "chat_id": 241233,
      "msg_id": 123
    },
    "badge": 1,
    "sound": "sound1.mp3",
    "mute": true
  }
}

CATATAN : lihat baris ini dalam kode di atas
"teks": "John Doe berbagi kontak di grup Kontak Exchange" dalam data payload, Anda harus menggunakan parameter "text" daripada parameter "body" atau "message" untuk deskripsi pesan atau apa pun yang Anda ingin menggunakan teks.

onMessageReceived ()

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.e(TAG, "From: " + remoteMessage.getData().toString());

        if (remoteMessage == null)
            return;

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
           /* Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());*/
            Log.e(TAG, "Data Payload: " + remoteMessage);

            try {

                Map<String, String> params = remoteMessage.getData();
                JSONObject json = new JSONObject(params);
                Log.e("JSON_OBJECT", json.toString());


                Log.e(TAG, "onMessageReceived: " + json.toString());

                handleDataMessage(json);
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }
Hiren
sumber
2

Sebut saja ini di Metode onCreate MainActivity Anda:

if (getIntent().getExtras() != null) {
           // Call your NotificationActivity here..
            Intent intent = new Intent(MainActivity.this, NotificationActivity.class);
            startActivity(intent);
        }
Aman Shekhar
sumber
Jika saya menavigasi dari mainActivity, bagaimana menavigasi kembali ke Kegiatan tertentu akan bekerja?
Mac_Play
2

menurut solusi dari t3h Exi saya ingin memposting kode bersih di sini. Masukkan saja ke MyFirebaseMessagingService dan semuanya berfungsi dengan baik jika aplikasi berada dalam mode latar belakang. Anda setidaknya perlu mengkompilasi com.google.firebase: firebase-messaging: 10.2.1

 @Override
public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }



           onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}
jujur
sumber
Saya mencoba menerapkan solusi Anda, tetapi metode handleIntent () adalah final dalam versi SDK saya (SDK 27), jadi saya tidak bisa
menimpanya
Ya tapi itu bukan salah saya atau alasan untuk memberi -1 !!! Sombong sekali. Ia bekerja sampai firebase 11.4.2 kemudian google mengubahnya (menjadikan metode ini final). Jadi sekarang Anda harus memprogram solusi Anda sendiri dengan pemberitahuan.
Frank
Saya tidak memberi -1 tetapi +1!
matdev
Anda menghemat pekerjaan saya: P
amitabha2715
2

Coba ini:

public void handleIntent(Intent intent) {
    try {
        if (intent.getExtras() != null) {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");
            for (String key : intent.getExtras().keySet()) {
            builder.addData(key, intent.getExtras().get(key).toString());
        }
            onMessageReceived(builder.build());
        } else {
            super.handleIntent(intent);
        }
    } catch (Exception e) {
        super.handleIntent(intent);
    }
}
pengguna3587828
sumber
handleIntent tidak lagi digunakan di firebase: 11.8.0 dan yang lebih tinggi.
Shihab Uddin
1

Saya mengalami masalah ini (aplikasi tidak ingin membuka pada klik pemberitahuan jika aplikasi di latar belakang atau tertutup), dan masalahnya adalah tidak valid click_actiondi badan pemberitahuan, coba hapus atau ubah menjadi sesuatu yang valid.

Lari Oktavianus
sumber
1

Poin yang patut disorot adalah bahwa Anda harus menggunakan pesan data - hanya data kunci - untuk mendapatkan handler onMessageReceived dipanggil bahkan ketika aplikasi di latar belakang. Anda seharusnya tidak memiliki kunci pesan pemberitahuan lainnya di payload Anda, jika tidak pawang tidak akan dipicu jika aplikasi di latar belakang.

Disebutkan (tetapi tidak begitu ditekankan dalam dokumentasi FCM) di sini:

https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

Gunakan server aplikasi dan API server FCM Anda: Tetapkan hanya kunci data . Dapat dilipat atau tidak dilipat.

n_y
sumber
1

Backend saya bekerja dengan menggunakan pesan Notifikasi dan bukan pesan Data. Jadi setelah membaca semua jawaban saya mencoba mengambil ekstra dari bundel niat yang datang ke aktivitas yang diluncurkan. Tapi tidak peduli kunci mana yang saya coba ambil getIntent().getExtras();, nilainya selalu nol.

Namun, saya akhirnya menemukan cara untuk mengirim data menggunakan pesan Notifikasi dan mengambilnya dari maksud.

Kuncinya di sini adalah menambahkan muatan data ke pesan Pemberitahuan.

Contoh:

{
    "data": {
        "message": "message_body",
        "title": "message_title"
    },
    "notification": {
        "body": "test body",
        "title": "test title"
    },
    "to": "E4An.."
}

Setelah Anda melakukan ini, Anda akan bisa mendapatkan info dengan cara ini:

intent.getExtras().getString("title") akan message_title

dan intent.getExtras().getString("message") akanmessage_body

Referensi

Vito Valov
sumber
1

Jika masalah Anda terkait dengan menampilkan Gambar Besar yaitu jika Anda mengirim pemberitahuan push dengan gambar dari konsol berbasis firebase dan itu akan menampilkan gambar hanya jika aplikasi di latar depan. Solusi untuk masalah ini adalah mengirim pesan push dengan hanya bidang data. Sesuatu seperti ini:

{ "data": { "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg", "message": "Firebase Push Message Using API" "AnotherActivity": "True" }, "to" : "device id Or Device token" }
Arun
sumber
Anda kehilangan koma sebelum "AnotherActivity". Android saya bergetar tetapi benar-benar tidak ada yang ditampilkan (tidak ada teks, tidak ada gambar, tidak ada dorongan).
jekaby
1

Ketika pesan diterima dan aplikasi Anda di latar belakang, pemberitahuan dikirim ke maksud ekstra dari kegiatan utama.

Anda dapat memeriksa nilai tambahan di fungsi oncreate () atau onresume () dari aktivitas utama.

Anda dapat memeriksa bidang-bidang seperti data, tabel dll (yang ditentukan dalam pemberitahuan)

misalnya saya kirim menggunakan data sebagai kuncinya

public void onResume(){
    super.onResume();
    if (getIntent().getStringExtra("data")!=null){
            fromnotification=true;
            Intent i = new Intent(MainActivity.this, Activity2.class);
            i.putExtra("notification","notification");
            startActivity(i);
        }

}
Sanjeev S
sumber
0

Saya mengalami masalah yang sama dan melakukan beberapa penggalian lebih lanjut tentang ini. Ketika aplikasi di latar belakang, pesan pemberitahuan dikirim ke baki sistem, TETAPI pesan data dikirim ke onMessageReceived()
Lihat https://firebase.google.com/docs/cloud-messaging/downstream#monitor-token-generation_3
dan https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java

Untuk memastikan bahwa pesan yang Anda kirim, dokumen mengatakan, " Gunakan server aplikasi Anda dan API server FCM: Tetapkan kunci data saja. Dapat dilipat atau tidak dilipat. "
Lihat https://firebase.google.com/ docs / cloud-messaging / concept-options # notification_and_data_messages

Eric B.
sumber
0

Ada dua jenis pesan: pesan pemberitahuan dan pesan data. Jika Anda hanya mengirim pesan data, itu tanpa objek notifikasi di string pesan Anda. Itu akan dipanggil ketika aplikasi Anda di latar belakang.

Shongsu
sumber
0

Periksa jawaban @Mahesh Kavathiya. Untuk kasus saya, dalam kode server hanya seperti ini:

{
"notification": {
  "body": "here is body",
  "title": "Title",
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

Anda perlu mengubah ke:

{
 "data": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
"notification": {
  "body": "here is body",
  "title": "Title"
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

Lalu, jika ada aplikasi di Latar Belakang, ekstra maksud aktivitas default akan mendapatkan "data"

Semoga berhasil!

huynq0911
sumber
-1

Cukup timpa metode OnCreate dari FirebaseMessagingService. Disebut ketika aplikasi Anda di latar belakang:

public override void OnCreate()
{
    // your code
    base.OnCreate();
}
Renzo Ciot
sumber
Jawaban ini bisa lebih bermanfaat jika Anda dapat menambahkan penjelasan, dan menautkan ke beberapa dokumentasi. Bisakah Anda memberi tahu kami bagaimana ini seharusnya membantu?
kilokahn
@kilokahn Bisakah Anda menjelaskan kepada saya apa yang tidak Anda mengerti? metode yang ditunjukkan harus dimasukkan dalam kode yang merupakan bagian dari pertanyaan dan sepenuhnya menjawab pertanyaan. Kode ini untuk Xamarin, tetapi Anda cukup mengonversi dalam java.
Renzo Ciot
AFAIK Dokumentasi resmi ( firebase.google.com/docs/cloud-messaging/android/client ) tidak berbicara tentang mengesampingkan OnCreate dalam layanan yang memperpanjang FirebaseMessagingService - jika Anda memiliki akses ke dokumentasi yang melakukannya, mungkin Anda dapat berbagi tautan? Juga, dari jawaban Anda, tidak jelas bagaimana mengesampingkan onCreate memecahkan masalah onMessageRivedived tidak dipanggil ketika pemberitahuan diklik - maka permintaan untuk informasi lebih lanjut.
kilokahn
Dokumentasi tidak menyebutkan penggantian metode OnCreate, tetapi berfungsi karena saya menggunakannya dalam produksi. Kode yang ingin Anda masukkan dalam metode onMessageReceived dan yang jelas berfungsi untuk melakukan beberapa operasi latar belakang dapat dilakukan di OnCreate.
Renzo Ciot
Dalam hal itu, menguraikan fakta bahwa itu entah bagaimana berhasil untuk Anda mungkin terbukti lebih bermanfaat daripada sekadar mendaftarkan solusi. Selain itu, perilaku tidak berdokumen cenderung berhenti bekerja secara sewenang-wenang dengan pembaruan, dan seseorang yang menggunakannya harus siap untuk mengolah kode mereka ketika hal itu terjadi. Penafian ini perlu dimasukkan.
kilokahn
-1

Ada 2 jenis dari Firebase push-notifikasi:

1- Pesan pemberitahuan (Pesan tampilan) -> - 1.1 Jika Anda memilih varian ini, OS akan membuat pemberitahuan sendiri jika aplikasi ada di Latar Belakang dan akan meneruskan data di intent. Maka terserah klien untuk menangani data ini.

- 1.2 Jika aplikasi berada di Foreground maka pemberitahuan itu akan diterima melalui callback-functiondi FirebaseMessagingServicedan terserah klien untuk menanganinya.

2- Pesan data (hingga data 4k) -> Pesan-pesan ini digunakan untuk hanya mengirim data ke klien (diam-diam) dan terserah klien untuk menanganinya untuk kedua kasus latar belakang / latar depan melalui fungsi panggil balik di FirebaseMessagingService

Ini sesuai dengan dokumen resmi: https://firebase.google.com/docs/cloud-messaging/concept-options

Balflear
sumber