Cordova-plugin-firebase: (Android) Klik pada notifikasi tidak memicu panggilan balik pada NotificationOpen

Dibuat pada 21 Sep 2016  ·  28Komentar  ·  Sumber: arnesson/cordova-plugin-firebase

Kordoba 6.3.1
Plugin firebase Phonegap 0.1.12
Perangkat: LG G5 dengan Android 6.0.1

Ini adalah kode yang saya gunakan:
`var aplikasi = {
// Konstruktor Aplikasi
inisialisasi: fungsi () {
this.bindEvents();
},
// Ikat Pendengar Acara
//
// Mengikat setiap peristiwa yang diperlukan saat startup. Acara yang umum adalah:
// 'memuat', 'deviceready', 'offline', dan 'online'.
bindEvents: fungsi () {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// Penangan Acara deviceready
//
// Ruang lingkup 'ini' adalah acara. Untuk memanggil 'receivedEvent'
// fungsi, kita harus memanggil 'app.receivedEvent(...);' secara eksplisit
onDeviceReady: fungsi () {
console.log ("Estamos dan onDeviceReady");
if (navigator.connection.type == Connection.NONE) {
navigator.notification.alert('Se memerlukan koneksi Internet');
} kalau tidak {
window.FirebasePlugin.onNotificationOpen(fungsi(pemberitahuan) {
console.log(pemberitahuan);
navigator.notification.alert ("Recibido");
}, fungsi (kesalahan) {
console.log(kesalahan);
});
}
},

};
app.initialize();`

Saya menerima pemberitahuan di baki sistem dalam semua situasi: aplikasi di latar belakang, latar depan dan tertutup dan ketika saya mengklik pemberitahuan, aplikasi terbuka dalam tiga kasus tetapi panggilan balik tidak dipicu.

Apakah ada yang salah dalam kode?

Terima kasih sebelumnya.

Komentar yang paling membantu

Saya telah menulis ulang seluruh penanganan onNotificationOpen dan membuatnya hampir berfungsi seperti yang saya harapkan, yaitu:

  • Pemberitahuan tiba dengan klien di latar depan, pemberitahuan terbuka dan onNotificationOpen dipanggil di klien saat ini (tanpa memuat ulang)
  • Pemberitahuan tiba dengan klien di latar belakang, pemberitahuan terbuka dan klien dibawa ke latar depan dan onNotificationOpen dipanggil dengan klien saat ini (tanpa memuat ulang)

Satu-satunya yang tersisa adalah agar pemberitahuan segera dikirimkan ke klien tanpa perlu dibuka, jika memungkinkan (belum memeriksanya).

Saya sedikit pemula Android, jadi mungkin ada beberapa perbaikan yang dapat dilakukan, tetapi tampaknya berfungsi dengan baik, jadi saya pikir saya akan membagikannya.

OnNotificationOpe nReceiver:onReceive sekarang cukup menelepon

FirebasePlugin.onBroadcastReceive(context, intent);

Mengubah FirebasePlugin sebagai berikut

  • hapus WeakReference dari callbackContext
  • tambahkan metode onBroadcastReceive, meneruskan data maksud ke onNotificationOpen
  • tambahkan metode onNewIntent, meneruskan data maksud ke onNotificationOpen
  • memulihkan versi lama onNotificationOpen dan mengubahnya sebagai berikut

    • menghapus baris Referensi Lemah

    • Ubah panggilan balik untuk menggunakan PluginResult dan panggil setKeepCallback(true) pada hasil untuk mencegah panggilan balik dihapus setelah panggilan pertama

    private static CallbackContext callbackContext;
    // ...
    private void registerOnNotificationOpen(final CallbackContext callbackContext) {
        FirebasePlugin.callbackContext = callbackContext;
    }

    // called when in foreground
    public static void onBroadcastReceive(Context context, Intent intent) {
        Log.d("FirebasePlugin", "onBroadcastReceive");
        Bundle data = intent.getExtras();
        FirebasePlugin.onNotificationOpen(data);
    }

    // called when in background
    <strong i="32">@Override</strong>
    public void onNewIntent(Intent intent) {
        Log.d(TAG, "new intent " + intent);
        super.onNewIntent(intent);
        FirebasePlugin.onNotificationOpen(intent.getExtras());
    }

    public static void onNotificationOpen(Bundle bundle) {
        if (FirebasePlugin.callbackContext == null ) {
            Log.d("FirebasePlugin", "no callback context, onNotificationOpen ignored");
            return;
        }
        if (callbackContext != null && bundle != null) {
            JSONObject json = new JSONObject();
            Set<String> keys = bundle.keySet();
            for (String key : keys) {
                try {
                    json.put(key, bundle.get(key));
                } catch (JSONException e) {
                    Log.d("FirebasePlugin", "onNotificationOpen: json exception");
                    PluginResult result = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
                    result.setKeepCallback(true);
                    callbackContext.sendPluginResult(result);
                    return;
                }
            }
            Log.d("FirebasePlugin", "onNotificationOpen: send notification to javascript");
            PluginResult result = new PluginResult(PluginResult.Status.OK, json);
            result.setKeepCallback(true);
            callbackContext.sendPluginResult(result);
        }
    }

Semua 28 komentar

masalah yang sama, pada notifikasi android tiba tetapi di dalam aplikasi tidak ada panggilan balik yang dipanggil.
v.0.1.12

@voidbrain @Kibukita tolong, uji versi terbaru dari repo. Saya mencoba meningkatkan notifikasi terbuka. Terima kasih.

@BugsBunnyBR Saya baru saja mencoba memperbarui ke versi terbaru dari repo dan baru saja mengujinya. Di Android masih belum menjalankan onNotificationOpen.

@superheroben , dapatkah Anda memberikan repo dengan contoh bagaimana Anda memanggil kode plugin? Bagaimana Anda mengirim notifikasi? Saya menguji dengan pesan topik.

Masalah yang sama disini.
getInstanceId() callback dipanggil, notifikasi tiba, tetapi onNotificationOpen() tidak pernah dipanggil.

Kode Klien:

if (window.FirebasePlugin)
{
  window.FirebasePlugin.getInstanceId(
    function(token) {
        thiss.saveToken(token);
    }, 
    function(error) {
        console.log(error);
    }
  );

  window.FirebasePlugin.onNotificationOpen(
    function(notification) {                  
      alert("Yeah!!!");                  
    }, 
    function(error) {
      alert("Error!");
      console.error(error);
    }
  );

  window.FirebasePlugin.grantPermission();
}

Struktur data notifikasi saya:

(
    [to] => (device token)
    [notification] => Array
        (
            [title] => Title
            [text] => Test message
            [sound] => default
            [vibrate] => 1
            [badge] => 2
        )
)

Kode sisi server saya (PHP):

$jsonData = json_encode($data);

$ch     = curl_init("https://fcm.googleapis.com/fcm/send");
$header = array(
    'Content-Type: application/json',
    "Authorization: key=".MY_GCM_API_KEY
);

curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, true);
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);

$result = curl_exec($ch);
curl_close($ch);

Bekerja pada Cordova Android 5.2.2. Perangkat yang digunakan untuk menguji menjalankan Android 4.4.2. Versi plugin 0.1.12.

@arivanbastos ,

Menginstal dari github sebagian memecahkan masalah. Terima kasih.

cordova plugin remove cordova-plugin-firebase
cordova plugin add https://github.com/arnesson/cordova-plugin-firebase/

Sekarang callback onNotificationOpen() dipanggil saat aplikasi berada di latar belakang.
Saat aplikasi berada di latar depan, alih-alih yang tertulis di dokumentasi, notifikasi tiba dan onNotificationOpen() tidak dipanggil:

Aplikasi di latar depan:
Pengguna menerima data pemberitahuan dalam panggilan balik JavaScript tanpa pemberitahuan apa pun pada perangkat itu sendiri (ini adalah perilaku normal pemberitahuan push, terserah Anda, pengembang, untuk memberi tahu pengguna)

Jika Anda mengirim push jenis "notifikasi" (tanpa badan data), notifikasi tidak akan ditampilkan saat aplikasi berada di latar depan.

Maaf, saya tidak mengerti. Haruskah saya menambahkan bagian "data" ke data notifikasi saya?

(
    [to] => (device token)
    [notification] => Array
        (
            [title] => Title
            [text] => Test message
        )
    [data] => Array
        (
            [test] => 1
        )
)

Ini tidak memperbaiki masalah.

Mengganti nama bagian "pemberitahuan" dengan "data" membuat aplikasi mogok ("Aplikasi telah berhenti") saat pemberitahuan tiba:

(
    [to] => (device token)
    [data] => Array
        (
            [title] => Title
            [text] => Test message
        )
)

https://firebase.google.com/docs/cloud-messaging/android/receive
Di sini dijelaskan dengan sangat baik.
Notifikasi Anda masuk ke System-Tray jika aplikasi berada di latar belakang dan ke onMessageReceived() jika aplikasi berada di latar depan.
Jika pesan Anda berisi data, maka ini selalu diteruskan ke onMessageReceived().

Saya pikir ada masalah dalam implementasi onMessageReceived().
Ketika saya melihat ke kode yang saya tafsirkan adalah sebagai berikut:

  • mengekstrak data
  • membuat notifikasi dengan NotificationBuilder
  • beri tahu melalui NotificationManager

NotificationManager.notify(id, notification) memposting notifikasi untuk ditampilkan di Status Bar.

Namun, bagi saya ini sepertinya diharapkan bahwa setiap saya menerima pesan dari FCM maka akan muncul notifikasi di Status Bar.
Saya tidak melihat pemeriksaan apakah Aplikasi ada di latar depan dan saya tidak melihat panggilan ke panggilan balik. Saya bukan pengembang Android jadi mungkin saya salah tetapi perilaku yang dijelaskan cocok untuk itu.

Oke, saya menemukan potongan kode yang memanggil panggilan balik.
Dengan komit terakhir dari BugsBunnyBR ada perubahan di OnNotificationOpenReceiver yang menjelaskan bahwa arivanbastos menjalankan panggilan baliknya saat menunjuk ke repo github.

Tapi tetap saja, notifikasi hanya dikirim (ke OnNotificationOpenReceiver dan NotificationManager) jika ada teks atau judul (dalam notifikasi atau data). Itu berarti tidak mungkin mengirim data ke aplikasi Anda tanpa mendapatkan notifikasi yang dikirim ke NotificationManager yang menunjukkannya di StatusBar.

@arivanbastos
Aku mengatakan sesuatu yang salah padamu. Maaf tentang itu.
Sudahkah Anda mencoba menunjuk ke versi repo ini?

@packowitz dan @robertarnesson . Oke, implementasi saya akan SELALU* mencoba menampilkan notifikasi. Atau pemberitahuan otomatis Firebase yang ditampilkan atau yang dibangun di dalam onMessageReceived akan ditampilkan.
Callback onNotificationOpen akan dipanggil saat onMessageReceived dipanggil atau saat notifikasi memiliki badan Data dan Notifikasi secara bersamaan. Dalam pr saya yang memperkenalkan onNotificationOpen saya mencoba menjelaskan bahwa pemberitahuan push dari jenis Pemberitahuan tidak akan mengaktifkan panggilan balik. Rekomendasinya adalah untuk selalu menyertakan badan Data dan badan Pemberitahuan, sehingga plugin dapat mendeteksi dan mengaktifkan panggilan balik.

Saya tahu bahwa, selalu menampilkan notifikasi bukanlah perilaku notifikasi Firebase standar.

Sebagian besar pengembang aplikasi Android ingin notifikasi mereka ditampilkan di baki sistem meskipun aplikasi berada di latar depan. Saya tahu ada kasus, seperti aplikasi obrolan, bahwa perilaku ini bukan hal yang baik.
Ketika saya mengembangkan fitur notifikasi Android, saya tidak peduli dengan kebutuhan aplikasi obrolan atau untuk mematuhi Firebase.

Yang bisa dilakukan adalah:
1) Kembangkan tanda untuk disetel saat aplikasi terbuka dengan mengatakan "hei, saya ingin Anda menampilkan notifikasi bahkan saat aplikasi terbuka" dan menggunakannya untuk mengontrol perilaku. Itu tidak perlu disimpan di penyimpanan apa pun jika aplikasi selalu menyetel tanda saat dibuka.

2) Cukup beri komentar pada baris ini dan nonaktifkan notifikasi saat aplikasi berada di latar depan.

_Always_ -> Jika plugin menemukan "teks" atau "judul" di badan notifikasi.

@BugsBunnyBR Saya suka ide memiliki bendera untuk memilih perilaku.
Saya akan memisahkan NotificationManager dari OnNotificationOpenReceiver memanggil kembali panggilan balik JS Anda. Rekomendasi saya adalah untuk memperkenalkan cek, jika ada data dalam pesan dan jika demikian maka panggil panggilan balik dengan data.
Untuk pemberitahuan akan lebih baik untuk memiliki bendera.
Terima kasih.

@BugsBunnyBR Saya baru saja menguji untuk beralih ke repo github dan menemukan bahwa mengetuk pemberitahuan memulai ulang aplikasi saya meskipun sudah berjalan. Terjadi bahkan ketika aplikasi berada di latar depan dan saya mengetuk notifikasi.
Tetapi panggilan balik berfungsi sekarang;)

Sama di sini, bagi saya versi 0.1.13 menyebabkan aplikasi saya restart tepat ketika berada di latar depan. Versi 0.1.12 bekerja dengan baik.

Pemberitahuan tidak berfungsi dengan baik dalam versi repo. Alasannya menurut saya, jika onNotificationOpen dipanggil sebelum notifikasi dibuka, maka akan diabaikan.

https://github.com/arnesson/cordova-plugin-firebase/blob/master/src/android/FirebasePlugin.java#L123

Di registerOnNotificationOpen itu hanya mendaftarkan panggilan balik JIKA ada notificationBundle menunggu

Juga, alasan aplikasi tampaknya memuat ulang jika sudah terbuka ada di OnNotificationOpenReceiver secara eksplisit dikatakan

launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

https://github.com/arnesson/cordova-plugin-firebase/blob/master/src/android/OnNotificationOpenReceiver.java#L17

yang memaksa klien untuk memuat ulang, di mana notificationBundle tersedia ketika panggilan balik onNotificationOpen terdaftar sehingga klien kemudian mendapatkan pemberitahuan.

Saya telah menulis ulang seluruh penanganan onNotificationOpen dan membuatnya hampir berfungsi seperti yang saya harapkan, yaitu:

  • Pemberitahuan tiba dengan klien di latar depan, pemberitahuan terbuka dan onNotificationOpen dipanggil di klien saat ini (tanpa memuat ulang)
  • Pemberitahuan tiba dengan klien di latar belakang, pemberitahuan terbuka dan klien dibawa ke latar depan dan onNotificationOpen dipanggil dengan klien saat ini (tanpa memuat ulang)

Satu-satunya yang tersisa adalah agar pemberitahuan segera dikirimkan ke klien tanpa perlu dibuka, jika memungkinkan (belum memeriksanya).

Saya sedikit pemula Android, jadi mungkin ada beberapa perbaikan yang dapat dilakukan, tetapi tampaknya berfungsi dengan baik, jadi saya pikir saya akan membagikannya.

OnNotificationOpe nReceiver:onReceive sekarang cukup menelepon

FirebasePlugin.onBroadcastReceive(context, intent);

Mengubah FirebasePlugin sebagai berikut

  • hapus WeakReference dari callbackContext
  • tambahkan metode onBroadcastReceive, meneruskan data maksud ke onNotificationOpen
  • tambahkan metode onNewIntent, meneruskan data maksud ke onNotificationOpen
  • memulihkan versi lama onNotificationOpen dan mengubahnya sebagai berikut

    • menghapus baris Referensi Lemah

    • Ubah panggilan balik untuk menggunakan PluginResult dan panggil setKeepCallback(true) pada hasil untuk mencegah panggilan balik dihapus setelah panggilan pertama

    private static CallbackContext callbackContext;
    // ...
    private void registerOnNotificationOpen(final CallbackContext callbackContext) {
        FirebasePlugin.callbackContext = callbackContext;
    }

    // called when in foreground
    public static void onBroadcastReceive(Context context, Intent intent) {
        Log.d("FirebasePlugin", "onBroadcastReceive");
        Bundle data = intent.getExtras();
        FirebasePlugin.onNotificationOpen(data);
    }

    // called when in background
    <strong i="32">@Override</strong>
    public void onNewIntent(Intent intent) {
        Log.d(TAG, "new intent " + intent);
        super.onNewIntent(intent);
        FirebasePlugin.onNotificationOpen(intent.getExtras());
    }

    public static void onNotificationOpen(Bundle bundle) {
        if (FirebasePlugin.callbackContext == null ) {
            Log.d("FirebasePlugin", "no callback context, onNotificationOpen ignored");
            return;
        }
        if (callbackContext != null && bundle != null) {
            JSONObject json = new JSONObject();
            Set<String> keys = bundle.keySet();
            for (String key : keys) {
                try {
                    json.put(key, bundle.get(key));
                } catch (JSONException e) {
                    Log.d("FirebasePlugin", "onNotificationOpen: json exception");
                    PluginResult result = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
                    result.setKeepCallback(true);
                    callbackContext.sendPluginResult(result);
                    return;
                }
            }
            Log.d("FirebasePlugin", "onNotificationOpen: send notification to javascript");
            PluginResult result = new PluginResult(PluginResult.Status.OK, json);
            result.setKeepCallback(true);
            callbackContext.sendPluginResult(result);
        }
    }

Humm... Saya perhatikan notifikasi tidak terkirim (ke perangkat) saat klien tidak berjalan (telah dimatikan).

Coba buka notifikasi yang disajikan oleh firebase secara langsung dan lihat perilakunya.. Saya kira mereka memulai kembali aktivitas utama yang menurut saya merupakan perilaku yang benar.

Maaf atas keterlambatannya. Saya mencoba dengan 0.1.13 tetapi aplikasi saya dimulai ulang setelah pemberitahuan terbuka.

ada berita ?

Saya tidak bisa mendapatkan panggilan balik onNotificationOpen yang berhasil atau gagal di Android menggunakan 0.1.17. Pengiriman melalui API atau GUI dengan payload tidak berfungsi. Ada saran?

Mengapa kita tidak membuat permintaan tarik dengan kode yang diposting @Mehuge ? Ini berfungsi seperti pesona di android untuk saya.

Saya harus memperbarui onNewIntent di FirebasePlugin untuk menyaring maksud peluncuran normal, jadi kode onNewIntent saya sekarang terlihat seperti ini

<strong i="6">@Override</strong>
public void onNewIntent(Intent intent) {
  Log.d(TAG, "new intent " + intent);
  super.onNewIntent(intent);
  Bundle data = intent.getExtras();
  if (data != null) {
    String id = data.getString("id");
    if (null != id) {
      FirebasePlugin.handleNotificationBundle(data);
    } else {
      Log.d(TAG, "Not a notification intent, ignored");
    }
  }
}

Saya tidak sepenuhnya senang dengan itu. Ini bekerja dengan mencari properti id dalam bundel maksud yang selalu dikirim oleh kode server saya. Tampaknya tidak ada apa pun yang ditambahkan GCM atau FBM secara andal ke bundel yang dapat digunakan untuk mengidentifikasi maksud sebagai pemberitahuan/pesan. Terkadang kami mendapatkan beberapa properti google yang ditambahkan (jika kami membuka notifikasi dari baki) tetapi untuk pesan dan notifikasi yang dikirim langsung ke klien saat berada di latar depan, tidak ada apa pun selain data dalam pesan yang memberi tahu Anda bahwa itu adalah maksud peluncuran karena pemberitahuan, setidaknya saya bisa melihat.

Mungkin ada cara yang lebih baik untuk menangani ini.

@Mehuge maukah Anda membuat Intisari dengan semua file yang Anda miliki?

Oke ini dia https://Gist.github.com/Mehuge/374ee24d9e18a6c7ccc171d3e521b7ad

Namun perhatikan, bahwa ada beberapa bit di sana yang khusus untuk aplikasi kami. Saya akhirnya memindahkan kode ke proyek kami karena saya banyak mengubahnya. Kalau dipikir-pikir, saya mungkin seharusnya mem-fork plugin dan memodifikasinya seperti itu, tetapi pada titik ini, saya jauh di belakang jadwal dan cukup muak dengan semuanya, jadi saya mengambil rute tercepat untuk membuat sesuatu berfungsi. Bit kustom cukup jelas, jadi harus cukup mudah untuk dikecualikan.

Perhatikan juga bahwa cara saya mengimplementasikan plugin, perlu mengetahui kapan klien dijeda (atau lebih khusus tidak dijeda) sehingga dapat memutuskan apakah akan membuat pemberitahuan atau mengirimkan pesan secara langsung. Anda mungkin atau mungkin tidak memerlukan fungsionalitas itu, tetapi dalam kasus kami, kami tidak ingin notifikasi yang dikirim saat klien berada di latar depan untuk membuat notifikasi android tetapi malah dikirimkan langsung ke klien untuk ditangani. Untuk menginformasikan plugin tentang status jeda klien, tambahkan kode berikut ke aktivitas utama Anda.

<strong i="9">@Override</strong>
protected void onResume() {
    FirebasePlugin.setPaused(false);
    super.onResume();
}

<strong i="10">@Override</strong>
protected void onPause() {
    FirebasePlugin.setPaused(true);
    super.onPause();
}

Ada masalah lain yang mungkin harus Anda hadapi, yaitu jika pemberitahuan tiba saat berada di latar belakang tetapi pengguna meluncurkan aplikasi secara langsung daripada dengan membuka pemberitahuan Android, Anda mungkin perlu mengatasinya dengan cara tertentu. Dalam kasus aplikasi kami, saya hanya dapat menghapus notifikasi yang belum dibuka. Situasi Anda mungkin berbeda.

Saya tidak sepenuhnya senang dengan hasil akhirnya, beberapa kunci tambahan yang ditambahkan misalnya bersifat eksperimental dan tidak benar-benar digunakan, saya hanya belum sempat menghapusnya.

Akan tertarik dengan umpan balik atau perbaikan yang disarankan atau menunjukkan kekurangan apa pun. Saya akan sangat tertarik untuk menemukan cara untuk mendeteksi maksud peluncuran dengan lebih baik dengan muatan GCM dari peluncuran normal. Saya menemukan properti google hanya ditambahkan dalam beberapa keadaan. Juga upaya saya untuk mendeteksi berbagai jenis notifikasi (is_push, is_notify, broadcast) tidak benar-benar berfungsi.

lihat #108

Bagi saya, saya bisa menyelesaikan membuat permintaan seperti ini:

{
  "registration_ids": [...tokens],
  "notification" : {
        "title": "Notf title",
        "body": "Notification body"
     },
     "data": {
        "click_action": "/call/dwEugLJ9PTVdcFb064CX"
     }
}

Tetapi saya harus mengambil click_action sebagai parameter dan melakukan pengalihan secara manual (saya menggunakan cordova dengan aplikasi reaksi).

Apakah halaman ini membantu?
0 / 5 - 0 peringkat