Codelab Firebase + WebRTC

1. Pengantar

Dalam codelab ini, Anda akan mempelajari cara membuat aplikasi chat video sederhana menggunakan WebRTC API di browser dan Cloud Firestore untuk pemberian sinyal. Aplikasi ini disebut FirebaseRTC dan berfungsi sebagai contoh sederhana yang akan mengajari Anda dasar-dasar pembuatan aplikasi berkemampuan WebRTC.

Yang akan Anda pelajari

  • Memulai panggilan video di aplikasi web menggunakan WebRTC
  • Memberi sinyal ke pihak jarak jauh menggunakan Cloud Firestore

Yang Anda butuhkan

Sebelum memulai codelab ini, pastikan Anda telah menginstal:

  • npm yang biasanya dilengkapi dengan Node.js - Node LTS direkomendasikan

2. Membuat dan menyiapkan project Firebase

Buat project Firebase

  1. Di Firebase console, klik Tambahkan project, lalu beri nama project FirebaseRTC FirebaseRTC.

Ingat Project ID untuk project Firebase Anda.

  1. Klik Buat project.

Aplikasi yang akan Anda buat menggunakan dua layanan Firebase yang tersedia di web:

  • Cloud Firestore untuk menyimpan data terstruktur di Cloud dan mendapatkan notifikasi instan saat data diperbarui
  • Firebase Hosting untuk menghosting dan menayangkan aset statis

Untuk codelab khusus ini, Anda sudah mengonfigurasi Firebase Hosting di project yang akan di-clone. Namun, untuk Cloud Firestore, kami akan memandu Anda dalam mengonfigurasi dan mengaktifkan layanan menggunakan Firebase console.

Mengaktifkan Cloud Firestore

Aplikasi ini menggunakan Cloud Firestore untuk menyimpan pesan chat dan menerima pesan chat baru.

Anda harus mengaktifkan Cloud Firestore:

  1. Di bagian Develop menu Firebase console, klik Database.
  2. Klik Buat database di panel Cloud Firestore.
  3. Pilih opsi Mulai dalam mode uji, lalu klik Aktifkan setelah membaca pernyataan penyangkalan tentang aturan keamanan.

Mode uji memastikan bahwa Anda dapat menulis database dengan bebas selama masa pengembangan. Nanti kita akan membuat database kita lebih aman di codelab ini.

3. Mendapatkan kode sampel

Clone repositori GitHub dari command line:

git clone https://github.com/webrtc/FirebaseRTC

Kode contoh seharusnya sudah di-clone ke direktori FirebaseRTC. Pastikan mulainya command line dari direktori ini mulai dari:

cd FirebaseRTC

Mengimpor aplikasi awal

Buka file dalam FirebaseRTC di editor Anda dan ubah file sesuai petunjuk di bawah ini. Direktori ini berisi kode awal untuk codelab yang terdiri dari aplikasi WebRTC yang belum fungsional. Kami akan membuatnya berfungsi di seluruh codelab ini.

4. Menginstal Antarmuka Command Line Firebase

Dengan Antarmuka Command Line (CLI) Firebase, Anda dapat menyalurkan aplikasi web secara lokal dan men-deploy aplikasi web ke Firebase Hosting.

  1. Instal CLI dengan menjalankan perintah npm berikut: sh npm -g install firebase-tools
  1. Pastikan bahwa CLI telah diinstal dengan benar dengan menjalankan perintah berikut: sh firebase --version

Pastikan versi Firebase CLI v6.7.1 atau lebih baru.

  1. Otorisasikan Firebase CLI dengan menjalankan perintah berikut: sh firebase login

Anda telah menyiapkan template aplikasi web untuk mengambil konfigurasi aplikasi Anda untuk Firebase Hosting dari direktori dan file lokal aplikasi Anda. Namun untuk melakukannya, Anda harus menautkan aplikasi dengan project Firebase.

  1. Kaitkan aplikasi Anda dengan project Firebase dengan menjalankan perintah berikut: sh firebase use --add

  2. Saat diminta, pilih Project ID Anda, lalu beri alias pada project Firebase Anda.

Alias berguna jika Anda memiliki beberapa lingkungan (produksi, staging, dll.). Namun, untuk codelab ini, cukup gunakan alias default.

  1. Ikuti petunjuk selanjutnya di command line.

5. Menjalankan server lokal

Anda sudah siap untuk membuat aplikasi Anda sendiri. Mari kita jalankan aplikasi secara lokal.

  1. Jalankan perintah Firebase CLI berikut: sh firebase serve --only hosting

  2. Command line Anda akan menampilkan respons berikut: hosting: Local server: http://localhost:5000

Kami menggunakan emulator Firebase Hosting untuk menayangkan aplikasi secara lokal. Aplikasi web kini seharusnya tersedia dari http://localhost:5000.

  1. Buka aplikasi Anda di http://localhost:5000.

Anda akan melihat salinan FirebaseRTC yang telah terhubung ke project Firebase.

Aplikasi telah terhubung ke project Firebase secara otomatis.

6. Membuat ruang baru

Di aplikasi ini, setiap sesi video chat disebut ruang. Pengguna dapat membuat ruang baru dengan mengklik tombol di aplikasi mereka. Tindakan ini akan menghasilkan ID yang dapat digunakan pihak jarak jauh untuk bergabung ke ruang yang sama. ID digunakan sebagai kunci di Cloud Firestore untuk setiap ruang.

Setiap kamar akan berisi RTCSessionDescriptions untuk penawaran dan jawaban, serta dua koleksi terpisah dengan kandidat ICE dari masing-masing pihak.

Tugas pertama Anda adalah menerapkan kode yang tidak ada untuk membuat ruang baru dengan penawaran awal dari pemanggil. Buka public/app.js dan temukan komentar // Add code for creating a room here lalu tambahkan kode berikut:

const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);

const roomWithOffer = {
    offer: {
        type: offer.type,
        sdp: offer.sdp
    }
}
const roomRef = await db.collection('rooms').add(roomWithOffer);
const roomId = roomRef.id;
document.querySelector('#currentRoom').innerText = `Current room is ${roomId} - You are the caller!`

Baris pertama membuat RTCSessionDescription yang akan mewakili penawaran dari pemanggil. Penetapan ini kemudian ditetapkan sebagai deskripsi lokal, dan terakhir ditulis pada objek ruang baru di Cloud Firestore.

Selanjutnya, kita akan memproses perubahan pada database dan mendeteksi saat jawaban dari tujuan panggilan telah ditambahkan.

roomRef.onSnapshot(async snapshot -> {
    console.log('Got updated room:', snapshot.data());
    const data = snapshot.data();
    if (!peerConnection.currentRemoteDescription && data.answer) {
        console.log('Set remote description: ', data.answer);
        const answer = new RTCSessionDescription(data.answer)
        await peerConnection.setRemoteDescription(answer);
    }
});

Ini akan menunggu hingga tujuan panggilan menulis RTCSessionDescription untuk jawabannya, dan menetapkannya sebagai deskripsi jarak jauh pada RTCPeerConnection pemanggil.

7. Bergabung ke ruang

Langkah berikutnya adalah menerapkan logika untuk bergabung ke ruang yang ada. Pengguna melakukannya dengan mengklik tombol Gabung ke ruang dan memasukkan ID untuk bergabung ke ruang. Tugas Anda di sini adalah untuk mengimplementasikan pembuatan RTCSessionDescription untuk jawaban dan memperbarui ruangan dalam database sesuai dengan itu.

const offer = roomSnapshot.data().offer;
await peerConnection.setRemoteDescription(offer);
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);

const roomWithAnswer = {
    answer: {
        type: answer.type,
        sdp: answer.sdp
    }
}
await roomRef.update(roomWithAnswer);

Dalam kode di atas, kita mulai dengan mengekstrak penawaran dari pemanggil dan membuat RTCSessionDescription yang ditetapkan sebagai deskripsi jarak jauh. Selanjutnya, kita membuat jawaban, menetapkannya sebagai deskripsi lokal, dan memperbarui database. Update database akan memicu callback onSnapshot di sisi pemanggil, yang kemudian akan menetapkan deskripsi jarak jauh berdasarkan jawaban dari tujuan panggilan. Hal ini menyelesaikan pertukaran objek RTCSessionDescription antara pemanggil dan tujuan panggilan.

8 Mengumpulkan kandidat ICE

Sebelum pemanggil dan tujuan panggilan dapat terhubung satu sama lain, mereka juga harus menukarkan kandidat ICE yang memberi tahu WebRTC cara terhubung ke peer jarak jauh. Tugas Anda berikutnya adalah menerapkan kode yang mendeteksi kandidat ICE dan menambahkannya ke koleksi dalam database. Temukan fungsi collectIceCandidates dan tambahkan kode berikut:

async function collectIceCandidates(roomRef, peerConnection,
                                    localName, remoteName) {
    const candidatesCollection = roomRef.collection(localName);

    peerConnection.addEventListener('icecandidate', event -> {
        if (event.candidate) {
            const json = event.candidate.toJSON();
            candidatesCollection.add(json);
        }
    });

    roomRef.collection(remoteName).onSnapshot(snapshot -> {
        snapshot.docChanges().forEach(change -> {
            if (change.type === "added") {
                const candidate = new RTCIceCandidate(change.doc.data());
                peerConnection.addIceCandidate(candidate);
            }
        });
    })
}

Fungsi ini melakukan dua hal. Metode ini mengumpulkan kandidat ICE dari WebRTC API dan menambahkannya ke database, serta memproses kandidat ICE yang ditambahkan dari pembanding jarak jauh dan menambahkannya ke instance RTCPeerConnection. Sangat penting saat memantau perubahan database untuk memfilter apa pun yang bukan tambahan baru, karena jika tidak, kita akan menambahkan kumpulan kandidat ICE yang sama berulang kali.

9. Kesimpulan

Dalam codelab ini, Anda telah mempelajari cara menerapkan sinyal untuk WebRTC menggunakan Cloud Firestore, serta cara menggunakannya untuk membuat aplikasi video chat yang sederhana.

Untuk mempelajari lebih lanjut, buka referensi berikut:

  1. Kode Sumber FirebaseRTC
  2. Contoh WebRTC
  3. Cloud Firestore