Mengizinkan permintaan kirim

Permintaan yang dikirim ke FCM dari server aplikasi atau lingkungan tepercaya harus diotorisasi. Perhatikan perbedaan penting antara otorisasi HTTP lama dan HTTP v1 API:

  • FCM HTTP v1 API mengizinkan permintaan dengan token akses OAuth 2.0 yang berumur pendek. Untuk membuat token ini, Anda dapat menggunakan Kredensial Default Aplikasi Google (di lingkungan server Google) dan/atau secara manual mendapatkan kredensial yang diperlukan dari file kunci pribadi JSON yang dihasilkan untuk akun layanan. Jika Anda menggunakan Firebase Admin SDK untuk mengirim pesan, library akan menangani token untuk Anda.
  • Protokol lama hanya dapat menggunakan kunci API yang berlaku panjang dari Firebase console.

Mengizinkan permintaan kirim HTTP v1

Tergantung detail lingkungan server Anda, gunakan kombinasi strategi ini untuk mengizinkan permintaan server ke layanan Firebase:

  • Kredensial Default Aplikasi (ADC) Google
  • File JSON akun layanan
  • Token akses OAuth 2.0 berumur pendek yang berasal dari akun layanan

Jika aplikasi Anda berjalan pada Compute Engine, Kubernetes Engine, App Engine, atau Cloud Functions (termasuk Cloud Functions for Firebase), gunakan Kredensial Default Aplikasi (ADC). ADC menggunakan akun layanan default yang sudah ada untuk mendapatkan kredensial guna mengizinkan permintaan, dan ADC mengaktifkan pengujian lokal fleksibel melalui variabel lingkungan GOOGLE_APPLICATION_CREDENTIALS. Untuk otomatisasi penuh alur otorisasi, gunakan ADC bersama dengan library server Admin SDK.

Jika aplikasi Anda berjalan di lingkungan server non-Google, Anda harus mendownload file JSON akun layanan dari project Firebase Anda. Selama Anda memiliki akses ke sistem file yang berisi file kunci pribadi, Anda dapat menggunakan variabel lingkungan GOOGLE_APPLICATION_CREDENTIALSuntuk mengizinkan permintaan dengan kredensial yang diperoleh secara manual ini. Jika Anda tidak memiliki akses file tersebut, Anda harus merujuk file akun layanan dalam kode Anda— yang harus dilakukan dengan sangat hati-hati karena dapat berisiko menampilkan kredensial Anda.

Memberikan kredensial dengan ADC

Kredensial Default Aplikasi (ADC) Google memeriksa kredensial Anda dengan urutan sebagai berikut:

  1. ADC memeriksa apakah variabel lingkungan GOOGLE_APPLICATION_CREDENTIALS ditetapkan. Jika variabel ditetapkan, ADC menggunakan file akun layanan yang ditunjuk variabel.

  2. Jika variabel lingkungan tidak ditetapkan, ADC menggunakan akun layanan default yang disediakan Compute Engine, Kubernetes Engine, App Engine, dan Cloud Functions untuk aplikasi yang berjalan pada layanan tersebut.

  3. Jika ADC tidak dapat menggunakan salah satu dari kredensial di atas, sistem akan memunculkan error.

Contoh kode Admin SDK berikut menggambarkan strategi ini. Contoh ini tidak secara eksplisit menentukan kredensial aplikasi. Namun, ADC secara implisit dapat menemukan kredensial selama variabel lingkungan ditetapkan, atau selama aplikasi berjalan pada Compute Engine, Kubernetes Engine, App Engine, atau Cloud Functions.

Node.js

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
});

Java

FirebaseOptions options = new FirebaseOptions.Builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/")
    .build();

FirebaseApp.initializeApp(options);

Python

default_app = firebase_admin.initialize_app()

Go

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C#

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
});

Memberikan kredensial secara manual

Project Firebase mendukung akun layanan Google, yang dapat Anda gunakan untuk memanggil API server Firebase dari server aplikasi atau lingkungan tepercaya. Jika Anda mengembangkan kode secara lokal atau men-deploy aplikasi secara lokal, gunakan kredensial yang diperoleh melalui akun layanan ini untuk mengizinkan permintaan server.

Untuk mengautentikasi akun layanan dan memberinya akses ke layanan Firebase, Anda harus membuat file kunci pribadi dalam format JSON.

Untuk membuat file kunci pribadi untuk akun layanan Anda:

  1. Di Firebase console, buka Setelan > Akun Layanan.

  2. Klik Buat Kunci Pribadi Baru, lalu konfirmasikan dengan mengklik Buat Kunci.

  3. Simpan dengan aman file JSON yang memuat kunci tersebut.

Saat memberi otorisasi melalui akun layanan, Anda diberi dua pilihan untuk memberikan kredensial ke aplikasi. Anda dapat menetapkan variabel lingkungan GOOGLE_APPLICATION_CREDENTIALS, atau secara eksplisit meneruskan jalur kunci akun layanan dalam kode. Opsi pertama lebih aman dan sangat direkomendasikan.

Untuk menetapkan variabel lingkungan:

Tetapkan variabel lingkungan GOOGLE_APPLICATION_CREDENTIALS ke jalur file JSON yang berisi kunci akun layanan Anda. Variabel ini hanya berlaku untuk sesi shell Anda saat ini, jadi jika Anda membuka sesi baru, tetapkan variabel lagi.

Linux atau macOS

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

Windows

Dengan PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

Setelah Anda menyelesaikan langkah-langkah di atas, Kredensial Default Aplikasi (ADC) secara implisit dapat menentukan kredensial Anda, sehingga Anda dapat menggunakan kredensial akun layanan saat menguji atau menjalankan di lingkungan non-Google.

Menggunakan kredensial untuk membuat token akses

Kecuali Anda menggunakan Admin SDK, yang menangani otorisasi secara otomatis, Anda harus membuat token akses dan menambahkannya untuk mengirim permintaan.

Gunakan kredensial Firebase Anda beserta Library Klien Google API untuk bahasa pilihan Anda saat mengambil token akses OAuth 2.0 yang berumur pendek:

node.js

 function getAccessToken() {
  return new Promise(function(resolve, reject) {
    const key = require('../placeholders/service-account.json');
    const jwtClient = new google.auth.JWT(
      key.client_email,
      null,
      key.private_key,
      SCOPES,
      null
    );
    jwtClient.authorize(function(err, tokens) {
      if (err) {
        reject(err);
        return;
      }
      resolve(tokens.access_token);
    });
  });
}

Dalam contoh ini, library klien Google API mengautentikasi permintaan dengan token web JSON atau JWT. Untuk informasi lebih lanjut, baca token web JSON.

Python

def _get_access_token():
  """Retrieve a valid access token that can be used to authorize requests.

  :return: Access token.
  """
  credentials = ServiceAccountCredentials.from_json_keyfile_name(
      'service-account.json', SCOPES)
  access_token_info = credentials.get_access_token()
  return access_token_info.access_token

Java

private static String getAccessToken() throws IOException {
  GoogleCredential googleCredential = GoogleCredential
      .fromStream(new FileInputStream("service-account.json"))
      .createScoped(Arrays.asList(SCOPES));
  googleCredential.refreshToken();
  return googleCredential.getAccessToken();
}

Setelah masa berlaku token akses berakhir, metode refresh token akan otomatis dipanggil untuk mengambil token yang telah diperbarui.

Untuk mengizinkan akses ke FCM, minta cakupan https://www.googleapis.com/auth/firebase.messaging.

Untuk menambahkan token akses ke header permintaan HTTP:

Tambahkan token sebagai nilai header Authorization dalam format Authorization: Bearer <access_token>:

node.js

headers: {
  'Authorization': 'Bearer ' + accessToken
}

Python

headers = {
  'Authorization': 'Bearer ' + _get_access_token(),
  'Content-Type': 'application/json; UTF-8',
}

Java

URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;

Mengizinkan permintaan pengiriman protokol lama

Dengan protokol HTTP lama, setiap permintaan harus berisi kunci server dari tab Cloud Messaging pada panel Setelan Firebase console. Untuk XMPP, Anda harus menggunakan kunci server yang sama untuk membuat koneksi.

Memigrasikan kunci server lama

Mulai Maret 2020, FCM berhenti membuat kunci server lama. Kunci server lama yang ada akan terus berfungsi, tetapi sebaiknya Anda menggunakan Kunci server berlabel versi yang lebih baru di Firebase console.

Jika ingin menghapus kunci server lama yang ada, Anda dapat melakukannya di Google Cloud Console.

Mengizinkan permintaan HTTP

Permintaan pesan terdiri dari dua bagian: header HTTP dan isi HTTP. Header HTTP harus berisi header berikut ini:

  • Authorization: key=YOUR_SERVER_KEY
    Pastikan ini adalah kunci server, yang value-nya tersedia di tab Cloud Messaging pada panel Setelan Firebase console. Kunci Android, iOS, dan browser ditolak oleh FCM.
  • Content-Type: application/json untuk JSON; application/x-www-form-urlencoded;charset=UTF-8 untuk teks biasa.
    Jika Content-Type dihilangkan, formatnya diasumsikan sebagai teks biasa.

Contoh:

Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
  "data" : {
    ...
  },
}

Baca artikel Membuat Permintaan Kirim untuk mengetahui detail selengkapnya mengenai pembuatan permintaan kirim. Referensi Protokol HTTP Lama menyediakan daftar semua parameter yang dapat dimuat di pesan Anda.

Memeriksa validitas kunci server

Jika Anda menerima error autentikasi saat mengirim pesan, periksa validitas kunci Server. Misalnya, pada Linux, jalankan perintah berikut:

api_key=YOUR_SERVER_KEY

curl --header "Authorization: key=$api_key" \
     --header Content-Type:"application/json" \
     https://fcm.googleapis.com/fcm/send \
     -d "{\"registration_ids\":[\"ABC\"]}"

Jika Anda menerima kode status HTTP 401, kunci Server Anda tidak valid.

Mengizinkan koneksi XMPP

Dengan XMPP, Anda dapat mempertahankan koneksi persisten, asinkron, dan dua arah ke server FCM. Koneksi dapat digunakan untuk mengirim dan menerima pesan antara server Anda dan perangkat pengguna yang tersambung ke FCM.

Anda dapat menggunakan sebagian besar library XMPP untuk mengelola koneksi yang berlaku panjang ke FCM. Endpoint XMPP berjalan pada fcm-xmpp.googleapis.com:5235. Saat menguji fungsi dengan pengguna nonproduksi, Anda harus terhubung ke server praproduksi di fcm-xmpp.googleapis.com:5236 (perhatikan port yang berbeda).

Pengujian rutin di praproduksi (lingkungan lebih kecil tempat build FCM terbaru berjalan) bermanfaat untuk mengisolasi pengguna nyata dari kode uji. Perangkat pengujian dan kode uji coba yang terhubung ke fcm-xmpp.googleapis.com:5236 harus menggunakan ID pengirim FCM yang berbeda untuk menghindari risiko pengiriman pesan uji coba kepada pengguna produksi atau pengiriman pesan upstream dari traffic produksi melalui koneksi pengujian.

Koneksi memiliki dua syarat penting:

  • Anda harus memulai koneksi Transport Layer Security (TLS). Perlu diperhatikan bahwa saat ini FCM tidak mendukung ekstensi STARTTLS.
  • FCM mewajibkan mekanisme autentikasi SASL PLAIN menggunakan <your_FCM_Sender_Id>@fcm.googleapis.com (ID pengirim FCM) dan kunci Server sebagai sandi. Nilai ini tersedia di tab Cloud Messaging di panel Setelan Firebase console.

Jika koneksi gagal, Anda harus segera menghubungkan ulang. Tidak perlu melakukan back-off jika pemutusan sambungan terjadi sesudah autentikasi. FCM mengizinkan 2.500 koneksi secara paralel untuk setiap ID pengirim.

Snippet berikut menggambarkan cara menjalankan autentikasi dan otorisasi untuk koneksi XMPP ke FCM.

Server XMPP

Server XMPP meminta koneksi ke FCM

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

FCM membuka koneksi dan meminta mekanisme autentikasi, yang mencakup metode PLAIN.

<stream:features>
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>X-OAUTH2</mechanism>
    <mechanism>X-GOOGLE-TOKEN</mechanism>
    <mechanism>PLAIN</mechanism>
  </mechanisms>
</stream:features>

Server XMPP

Server XMPP harus merespons menggunakan metode autentikasi PLAIN, yang menyediakan kunci server dari tab Cloud Messaging pada panel Setelan Firebase console.

<auth mechanism="PLAIN"
xmlns="urn:ietf:params:xml:ns:xmpp-sasl">MTI2MjAwMzQ3OTMzQHByb2plY3RzLmdjbS5hb
mFTeUIzcmNaTmtmbnFLZEZiOW1oekNCaVlwT1JEQTJKV1d0dw==</auth>

FCM

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

Server XMPP

<stream:stream to="fcm.googleapis.com"
        version="1.0" xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams">

FCM

<stream:features>
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

Server XMPP

<iq type="set">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"></bind>
</iq>

FCM

<iq type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>SENDER_ID@fcm.googleapis.com/RESOURCE</jid>
  </bind>
</iq>

Catatan: FCM tidak menggunakan resource terikat saat merutekan pesan.

Baca artikel Membuat Permintaan Kirim untuk mengetahui detail selengkapnya mengenai pembuatan permintaan kirim. Referensi Protokol XMPP Lama menyediakan daftar semua parameter yang dapat dimuat di pesan Anda.