Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Lingkungan server dan FCM Anda

Sisi server Firebase Cloud Messaging terdiri dari dua komponen:

  • Backend FCM yang disediakan oleh Google.
  • Server aplikasi Anda atau lingkungan server tepercaya lainnya untuk menjalankan logika server, seperti Cloud Functions for Firebase atau lingkungan cloud lain yang dikelola oleh Google.

Server aplikasi Anda atau lingkungan server tepercaya mengirimkan permintaan pesan ke backend FCM, yang kemudian merutekan pesan ke aplikasi klien yang berjalan di perangkat pengguna.

Persyaratan untuk lingkungan server tepercaya

Lingkungan server aplikasi Anda harus memenuhi kriteria berikut:

  • Mampu mengirim permintaan pesan yang diformat dengan baik ke backend FCM.
  • Mampu menangani permintaan dan mengirimnya kembali menggunakan back-off eksponensial.
  • Mampu menyimpan kredensial otorisasi server dan token pendaftaran klien dengan aman.
  • Untuk protokol XMPP (jika digunakan), server harus mampu menghasilkan ID pesan sebagai identifikasi unik bagi setiap pesan yang dikirimkannya (backend HTTP FCM menghasilkan ID pesan dan menampilkannya dalam balasan). ID pesan XMPP harus unik per ID pengirim.

Memilih opsi server

Anda harus memutuskan metode interaksi dengan server FCM: baik menggunakan Firebase Admin SDK maupun protokol mentah. Karena mendukung seluruh bahasa pemrograman populer dan metode praktisnya untuk menangani autentikasi dan otorisasi, Firebase Admin SDK adalah metode yang direkomendasikan.

Opsi untuk berinteraksi dengan server FCM meliputi hal berikut:
  • Firebase Admin SDK, yang mendukung Node, Java, Python, C#, dan Go.
  • FCM HTTP v1 API, yang merupakan opsi protokol terbaru, dengan otorisasi yang lebih aman dan kemampuan pengiriman pesan lintas platform yang fleksibel (Firebase Admin SDK didasarkan pada protokol ini dan memberikan semua keuntungan yang dimilikinya).
  • Protokol HTTP lama.
  • Protokol server XMPP. Perlu diperhatikan bahwa jika Anda ingin menggunakan pengiriman upstream dari aplikasi klien, Anda harus menggunakan XMPP.

Firebase Admin SDK untuk FCM

Admin FCM API menangani autentikasi dengan backend dan memfasilitasi pengiriman pesan serta mengelola langganan topik. Dengan Firebase Admin SDK, Anda dapat:

  • Mengirim pesan ke satu perangkat
  • Mengirim pesan ke topik dan pernyataan kondisi yang cocok dengan satu topik atau lebih.
  • Membuat perangkat berlangganan ke topik dan berhenti berlangganan dari topik.
  • Membuat payload pesan yang disesuaikan untuk berbagai platform target

Admin Node.js SDK menyediakan metode untuk mengirim pesan ke grup perangkat.

Untuk menyiapkan Firebase Admin SDK, baca bagian Menambahkan Firebase Admin SDK ke Server Anda. Jika Anda sudah memiliki project Firebase, mulailah dengan Menambahkan SDK. Kemudian, setelah Firebase Admin SDK diinstal, Anda dapat langsung menulis logika untuk mem-build permintaan kirim.

Protokol Server FCM

Saat ini, FCM menyediakan protokol server mentah berikut:

Server aplikasi Anda dapat menggunakan semua protokol ini secara terpisah atau berpasangan. Sebagai protokol yang paling baru dan fleksibel untuk mengirim pesan ke beberapa platform, FCM HTTP v1 API direkomendasikan di mana pun dimungkinkan. Jika persyaratan Anda mencakup pengiriman pesan upstream dari perangkat ke server, Anda harus menerapkan protokol XMPP.

Pengiriman pesan XMPP berbeda dari pengiriman pesan HTTP dalam hal berikut:

  • Pesan Upstream/Downstream
    • HTTP: Hanya downstream, dari cloud ke perangkat.
    • XMPP: Upstream dan downstream (perangkat ke cloud, cloud ke perangkat).
  • Pengiriman pesan (sinkron atau asinkron)
    • HTTP: Sinkron. Server aplikasi mengirim pesan sebagai permintaan HTTP POST dan menunggu respons. Mekanisme ini bersifat sinkron dan memblokir pengirim agar tidak mengirim pesan lain hingga respons diterima.
    • XMPP: Asinkron. Server aplikasi mengirim/menerima pesan ke/dari semua perangkatnya dengan kecepatan baris penuh tertinggi melalui koneksi XMPP persisten. Server koneksi XMPP mengirim notifikasi konfirmasi atau kegagalan (dalam format pesan XMPP berenkode ACK dan NACK JSON khusus) secara asinkron.
  • JSON
    • HTTP: Pesan JSON dikirim sebagai HTTP POST.
    • XMPP: Pesan JSON dibungkus dalam pesan XMPP.
  • Teks Biasa
    • HTTP: Pesan Teks Biasa dikirim sebagai HTTP POST.
    • XMPP: Tidak didukung.
  • Downstream multicast mengirim ke beberapa token pendaftaran.
  • HTTP: Didukung dalam format pesan JSON.
  • XMPP: Tidak didukung.

Mengimplementasikan protokol server HTTP

Untuk mengirim pesan, server aplikasi akan menerbitkan permintaan POST dengan header HTTP dan isi HTTP yang terdiri dari key-value pair JSON. Untuk detail tentang opsi header dan isi, lihat Membuat Permintaan Pengiriman Server Aplikasi

Mengimplementasikan protokol server XMPP

Payload JSON untuk pesan FCM mirip dengan protokol HTTP, dengan pengecualian berikut:

  • Tidak ada dukungan untuk banyak penerima.
  • FCM menambahkan kolom message_id, yang merupakan kolom wajib. ID ini secara unik mengidentifikasi pesan dalam koneksi XMPP. ACK atau NACK dari FCM menggunakan message_id untuk mengidentifikasi pesan yang dikirimkan dari server aplikasi ke FCM. Oleh karena itu, message_id tidak hanya harus unik (per ID pengirim), tetapi juga harus selalu ada.
  • XMPP menggunakan kunci server untuk mengotorisasi koneksi tetap ke FCM. Lihat Mengotorisasi Permintaan Kirim untuk mengetahui informasi lebih lanjut.

Selain pesan FCM biasa, pesan kontrol juga dikirim, yang ditunjukkan oleh kolom message_type dalam object JSON. Nilainya bisa 'ack' atau 'nack', atau 'control' (lihat format di bawah). Setiap pesan FCM dengan message_type yang tidak dikenal bisa diabaikan oleh server Anda.

Server aplikasi perlu mengirim pesan ACK untuk setiap pesan perangkat yang diterima dari FCM. Server tidak perlu mengirim pesan NACK. Jika Anda tidak mengirim ACK untuk pesan, FCM akan mengirimnya ulang pada saat koneksi XMPP baru dibuat lagi, kecuali jika masa berlaku pesan tersebut sudah habis terlebih dahulu.

FCM juga mengirim pesan ACK atau NACK untuk setiap pesan server ke perangkat. Jika Anda tidak menerima salah satunya, berarti koneksi TCP tertutup saat operasi berlangsung dan server perlu mengirim ulang pesan tersebut. Baca bagian Kontrol Alur untuk mengetahui detailnya.

Baca Referensi Protokol untuk melihat daftar semua parameter pesan.

Format permintaan

Pesan dengan payload — pesan notifikasi

Berikut ini stanza XMPP untuk pesan notifikasi:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
     "notification": {
        "title": "Portugal vs. Denmark”,
        "body”: "5 to 1”
      },
      "time_to_live":"600"
}

  }
  </gcm>
</message>

Pesan dengan payload — pesan data

Berikut ini stanza XMPP yang berisi pesan JSON dari server aplikasi ke FCM:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
      "message_id":"m-1366082849205" // new required field
      "data":
      {
          "hello":"world",
      }
      "time_to_live":"600",
  }
  </gcm>
</message>

Format respons

Respons FCM bisa memiliki tiga kemungkinan format. Yang pertama adalah pesan 'ack' biasa. Tetapi jika respons tersebut berisi error, pesan tersebut bisa muncul dalam 2 format lain, yang dijelaskan di bawah ini.

Pesan ACK

Berikut ini stanza XMPP yang berisi pesan ACK/NACK dari FCM ke server aplikasi:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

Pesan NACK

Error NACK merupakan pesan XMPP biasa yang pesan status message_type-nya adalah "nack". Pesan NACK berisi:

  • Kode error NACK.
  • Deskripsi error NACK.

Berikut ini adalah beberapa contoh.

Pendaftaran buruk:

<message>
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"SomeInvalidRegistrationId",
    "error":"BAD_REGISTRATION",
    "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId"
  }
  </gcm>
</message>

JSON tidak valid:

<message>
 <gcm xmlns="google:mobile:data">
 {
   "message_type":"nack",
   "message_id":"msgId1",
   "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "error":"INVALID_JSON",
   "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc"
 }
 </gcm>
</message>

Jumlah Pesan Perangkat Terlampaui:

<message id="...">
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"REGID",
    "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
    "error_description":"Downstream message rate exceeded for this registration id"
  }
  </gcm>
</message>

Baca Referensi Server untuk melihat daftar lengkap kode error NACK. Pesan ber-NACK tidak boleh dicoba lagi, kecuali jika ada ketentuan lain. Kode error NACK yang tidak terduga harus diperlakukan sama dengan INTERNAL_SERVER_ERROR.

Error stanza

Anda juga bisa mengalami error stanza dalam kasus tertentu. Error stanza berisi:

  • Kode error stanza.
  • Deskripsi error stanza (teks bebas).

Misalnya:

<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC">
  <gcm xmlns="google:mobile:data">
     {"random": "text"}
  </gcm>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
    </text>
  </error>
</message>

Pesan kontrol

FCM perlu menutup koneksi secara berkala untuk melakukan load balancing. Sebelum menutup koneksi, FCM mengirim pesan CONNECTION_DRAINING untuk menunjukkan bahwa koneksi sedang dikuras dan akan segera ditutup. "Pengurasan" adalah penutupan aliran pesan yang masuk ke koneksi, tapi mengizinkan apa pun yang sudah ada dalam pipeline untuk terus mengalir. Saat menerima pesan CONNECTION_DRAINING, Anda harus segera mulai mengirimkan pesan ke koneksi FCM lain, dengan membuka koneksi baru jika perlu. Walaupun demikian, Anda harus tetap membuka koneksi asal dan terus menerima pesan yang mungkin datang melalui koneksi tersebut (dan meng-ACK pesan tersebut). FCM akan memulai penutupan koneksi ketika telah siap.

Pesan CONNECTION_DRAINING terlihat seperti ini:

<message>
  <data:gcm xmlns:data="google:mobile:data">
  {
    "message_type":"control"
    "control_type":"CONNECTION_DRAINING"
  }
  </data:gcm>
</message>

Saat ini, satu-satunya control_type yang didukung adalah CONNECTION_DRAINING.

Kontrol alur

Setiap pesan yang dikirim ke FCM akan menerima respons ACK atau NACK. Pesan yang belum menerima salah satu respons ini dianggap tertunda. Jika pesan tertunda mencapai 100, server aplikasi akan berhenti mengirim pesan baru dan menunggu FCM untuk mengonfirmasi beberapa pesan tertunda, seperti ditunjukkan dalam gambar 1:

Gambar 1. Alur pesan/ack.

Sebaliknya, agar server aplikasi tidak kelebihan muatan, FCM berhenti mengirim jika ada terlalu banyak pesan yang tidak terkonfirmasi. Oleh sebab itu, server aplikasi harus meng-"ACK" pesan upstream, yang diterima dari aplikasi klien melalui FCM, sesegera mungkin agar alur pesan masuk tetap konstan. Batas pesan tertunda yang disebutkan di atas tidak berlaku untuk ACK ini. Bahkan jika jumlah pesan tertunda mencapai 100, server aplikasi harus terus mengirim ACK untuk pesan yang diterima dari FCM, agar pengiriman pesan upstream baru tidak terblokir.

ACK hanya valid dalam konteks satu koneksi. Jika koneksi tertutup sebelum pesan bisa ditandai sebagai ACK, server aplikasi harus menunggu FCM mengirim ulang pesan upstream sebelum menandainya sebagai ACK lagi. Demikian juga, semua pesan tertunda yang belum menerima ACK/NACK dari FCM sebelum koneksi tertutup harus dikirim lagi.