Codelab Firebase + WebRTC

1. Pengantar

Dalam codelab ini, Anda akan mempelajari cara membangun aplikasi video chat sederhana menggunakan WebRTC API di browser Anda dan Cloud Firestore untuk pemberian sinyal. Tujuan disebut FirebaseRTC dan berfungsi sebagai contoh sederhana yang akan mengajarkan dasar-dasar membangun aplikasi dengan 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

Membuat project Firebase

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

Ingat Project ID untuk project Firebase Anda.

  1. Klik Buat project.

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

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

Untuk codelab khusus ini, Anda telah mengonfigurasi Firebase Hosting di yang akan Anda kloning. Namun, untuk Cloud Firestore, kami akan memandu Anda konfigurasi dan pengaktifan layanan menggunakan Firebase console.

Mengaktifkan Cloud Firestore

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

Anda harus mengaktifkan Cloud Firestore:

  1. Di bagian Develop pada menu Firebase console, klik Database.
  2. Klik Buat database di panel Cloud Firestore.
  3. Pilih opsi Start in test mode, lalu klik Enable setelah membaca pernyataan penyangkalan tentang aturan keamanan.

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

3. Mendapatkan kode contoh

Buat clone repositori GitHub dari command line:

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

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

cd FirebaseRTC

Mengimpor aplikasi awal

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

4. Menginstal Antarmuka Command Line Firebase

Antarmuka Command Line (CLI) Firebase memungkinkan Anda menyalurkan aplikasi web secara lokal dan men-deploy aplikasi web Anda 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 yang lebih baru.

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

Anda telah menyiapkan template aplikasi web untuk mengambil konfigurasi aplikasi untuk Firebase Hosting dari file dan direktori lokal aplikasi Anda. Tetapi untuk melakukan ini, Anda perlu mengaitkan aplikasi dengan project Firebase.

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

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

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

  1. Ikuti petunjuk selanjutnya di command line.

5. Menjalankan server lokal

Anda sudah siap untuk mulai mengerjakan aplikasi kami! 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

Kita menggunakan emulator Firebase Hosting untuk menyalurkan aplikasi secara lokal. Aplikasi web sekarang seharusnya tersedia dari {i>http://localhost:5000<i}.

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

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

Aplikasi telah terhubung secara otomatis ke project Firebase Anda.

6. Membuat ruang baru

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

Setiap kamar akan berisi RTCSessionDescriptions untuk penawaran dan serta dua kumpulan terpisah dengan kandidat ICE dari setiap partai.

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. Ini kemudian ditetapkan sebagai deskripsi lokal, dan akhirnya ditulis ke objek ruang baru di Cloud Firestore.

Selanjutnya, kita akan memproses perubahan pada {i>database<i} dan mendeteksi ketika 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 jawab, dan setel sebagai deskripsi jarak jauh di penelepon RTCPeerConnection.

7. Bergabung ke ruang

Langkah berikutnya adalah menerapkan logika untuk bergabung ke ruang yang ada. Pengguna melakukannya dengan mengklik tombol Gabung ke ruang, lalu memasukkan ID ruang tersebut untuk bergabung. Tugas Anda di sini adalah menerapkan pembuatan RTCSessionDescription untuk menjawab dan memperbarui ruang di database sebagaimana mestinya.

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);

Pada kode di atas, kita mulai dengan mengekstrak penawaran dari pemanggil dan membuat RTCSessionDescription yang kita tetapkan sebagai deskripsi jarak jauh. Selanjutnya, kita membuat jawabannya, menetapkannya sebagai deskripsi lokal, dan memperbarui {i>database<i}. Update database akan memicu callback onSnapshot di sisi pemanggil, yang pada gilirannya akan mengatur deskripsi jarak jauh berdasarkan jawaban dari penerima panggilan. Tindakan ini menyelesaikan pertukaran objek RTCSessionDescription antara penelepon dan penerima panggilan.

8. Mengumpulkan kandidat ICE

Sebelum penelepon dan penerima panggilan dapat terhubung satu sama lain, mereka juga harus bertukar kandidat ICE yang memberi tahu WebRTC cara terhubung ke peer jarak jauh. Tugas Anda selanjutnya adalah menerapkan kode yang memproses kandidat ICE dan menambahkan mereka ke koleksi dalam {i>database<i}. 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. API ini mengumpulkan kandidat ICE dari WebRTC API dan menambahkannya ke {i>database<i}, dan memproses kandidat ICE yang ditambahkan dari jarak jauh peer dan menambahkannya ke instance RTCPeerConnection-nya. Penting ketika mendengarkan perubahan {i>database<i} untuk memfilter apa pun yang bukan merupakan tambahan baru, karena jika tidak, kami akan menambahkan kumpulan kandidat ICE yang sama berulang kali untuk mencoba lagi perintah.

9. Kesimpulan

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

Untuk mempelajari lebih lanjut, buka referensi berikut:

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