1. Ringkasan
Dalam codelab ini, Anda akan mempelajari beberapa dasar Firebase untuk membuat aplikasi web interaktif. Anda akan membangun aplikasi RSVP acara dan chat buku tamu menggunakan beberapa produk Firebase.
Hal yang akan Anda pelajari
- Lakukan autentikasi pengguna dengan Firebase Authentication dan FirebaseUI.
- Menyinkronkan data menggunakan Cloud Firestore.
- Tulis Aturan Keamanan Firebase untuk mengamankan database.
Hal yang akan Anda perlukan
- Browser pilihan Anda, seperti Chrome.
- Akses ke stackblitz.com (tidak perlu akun atau login).
- Akun Google, seperti akun Gmail. Sebaiknya gunakan akun email yang sudah digunakan untuk akun GitHub Anda. Hal ini memungkinkan Anda untuk menggunakan fitur lanjutan di StackBlitz.
- Kode contoh codelab. Lihat langkah berikutnya untuk mengetahui cara mendapatkan kode.
2. Mendapatkan kode awal
Dalam codelab ini, Anda akan membangun aplikasi menggunakan StackBlitz, editor online yang memiliki beberapa alur kerja Firebase yang terintegrasi di dalamnya. Stackblitz tidak memerlukan penginstalan software atau akun StackBlitz khusus.
StackBlitz memungkinkan Anda berbagi proyek dengan orang lain. Orang lain yang memiliki URL project StackBlitz dapat melihat kode dan melakukan fork pada project, tetapi mereka tidak dapat mengedit project StackBlitz.
- Buka URL ini untuk kode awal: https://stackblitz.com/edit/firebase-gtk-web-start
- Di bagian atas halaman StackBlitz, klik Fork:
Sekarang, Anda memiliki salinan kode awal sebagai project StackBlitz, yang memiliki nama unik, beserta URL unik. Semua file dan perubahan Anda disimpan di project StackBlitz ini.
3. Edit informasi acara
Materi awal codelab ini menyediakan beberapa struktur untuk aplikasi web, termasuk beberapa stylesheet dan beberapa penampung HTML untuk aplikasi. Nanti dalam codelab ini, Anda akan mengaitkan container ini ke Firebase.
Untuk memulai, mari kita lebih akrab dengan antarmuka StackBlitz.
- Di StackBlitz, buka file
index.html
. - Temukan
event-details-container
dandescription-container
, lalu coba edit beberapa detail peristiwa.
Saat Anda mengedit teks, pemuatan ulang halaman otomatis di StackBlitz akan menampilkan detail peristiwa baru. Keren, ya?
<!-- ... -->
<div id="app">
<img src="..." />
<section id="event-details-container">
<h1>Firebase Meetup</h1>
<p><i class="material-icons">calendar_today</i> October 30</p>
<p><i class="material-icons">location_city</i> San Francisco</p>
</section>
<hr>
<section id="firebaseui-auth-container"></section>
<section id="description-container">
<h2>What we'll be doing</h2>
<p>Join us for a day full of Firebase Workshops and Pizza!</p>
</section>
</div>
<!-- ... -->
Pratinjau aplikasi Anda akan terlihat seperti ini:
Pratinjau aplikasi
4. Membuat dan menyiapkan project Firebase
Menampilkan informasi acara bagus untuk tamu Anda, tetapi hanya menampilkan acara tidak terlalu berguna bagi siapa pun. Mari kita tambahkan beberapa fungsi dinamis ke aplikasi ini. Untuk melakukannya, Anda harus menghubungkan Firebase ke aplikasi. Untuk memulai Firebase, Anda harus membuat dan menyiapkan project Firebase.
Membuat project Firebase
- Login ke Firebase.
- Di Firebase console, klik Add Project (atau Create a project), lalu beri nama project Firebase Anda sebagai Firebase-Web-Codelab.
- Klik opsi pembuatan project. Setujui persyaratan Firebase jika diminta. Di layar Google Analytics, klik "Jangan Aktifkan", karena Anda tidak akan menggunakan Analytics untuk aplikasi ini.
Untuk mempelajari project Firebase lebih lanjut, lihat artikel Memahami project Firebase.
Mengaktifkan dan menyiapkan produk Firebase di konsol
Aplikasi yang Anda build menggunakan beberapa produk Firebase yang tersedia untuk aplikasi web:
- Firebase Authentication dan UI Firebase untuk memudahkan pengguna login ke aplikasi Anda.
- Cloud Firestore untuk menyimpan data terstruktur di cloud dan mendapatkan notifikasi instan saat data berubah.
- Aturan Keamanan Firebase untuk mengamankan database Anda.
Beberapa produk ini memerlukan konfigurasi khusus atau harus diaktifkan menggunakan Firebase console.
Mengaktifkan login dengan email untuk Firebase Authentication
Untuk mengizinkan pengguna login ke aplikasi web, Anda akan menggunakan metode login Email/Sandi untuk codelab ini:
- Di panel sebelah kiri Firebase console, klik Build > Authentication. Kemudian, klik Mulai. Anda kini berada di dasbor Authentication, tempat Anda dapat melihat pengguna yang login, mengonfigurasi penyedia login, dan mengelola setelan.
- Pilih tab Metode login (atau klik di sini untuk langsung membuka tab).
- Klik Email/Sandi dari opsi penyedia, alihkan tombol ke Aktifkan, lalu klik Simpan.
Menyiapkan Cloud Firestore
Aplikasi web menggunakan Cloud Firestore untuk menyimpan pesan chat dan menerima pesan chat baru.
Berikut cara menyiapkan Cloud Firestore di project Firebase Anda:
- Di panel kiri Firebase console, luaskan Build, lalu pilih Firestore database.
- Klik Buat database.
- Biarkan Database ID disetel ke
(default)
. - Pilih lokasi untuk database Anda, lalu klik Berikutnya.
Untuk aplikasi yang sebenarnya, Anda harus memilih lokasi yang dekat dengan pengguna. - Klik Mulai dalam mode pengujian. Baca pernyataan penyangkalan tentang aturan keamanan.
Di bagian akhir codelab ini, Anda akan menambahkan Aturan Keamanan untuk mengamankan data. Jangan mendistribusikan atau mengekspos aplikasi ke publik tanpa menambahkan Aturan Keamanan untuk database Anda. - Klik Buat.
5. Menambahkan dan mengonfigurasi Firebase
Setelah membuat project Firebase dan beberapa layanan diaktifkan, Anda harus memberi tahu kode bahwa Anda ingin menggunakan Firebase, serta project Firebase yang akan digunakan.
Menambahkan library Firebase
Agar aplikasi Anda dapat menggunakan Firebase, Anda perlu menambahkan library Firebase ke aplikasi. Ada beberapa cara untuk melakukannya, seperti dijelaskan dalam dokumentasi Firebase. Misalnya, Anda dapat menambahkan pustaka dari CDN Google, atau Anda dapat menginstalnya secara lokal menggunakan npm, lalu mengemasnya di aplikasi jika Anda menggunakan Browserify.
StackBlitz menyediakan pemaketan otomatis sehingga Anda dapat menambahkan library Firebase menggunakan pernyataan impor. Anda akan menggunakan library versi modular (v9), yang membantu mengurangi ukuran halaman web secara keseluruhan melalui proses yang disebut "tree shaking". Anda dapat mempelajari SDK modular lebih lanjut di dokumen.
Untuk mem-build aplikasi ini, Anda menggunakan library Firebase Authentication, FirebaseUI, dan Cloud Firestore. Untuk codelab ini, pernyataan impor berikut sudah disertakan di bagian atas file index.js
, dan kita akan mengimpor lebih banyak metode dari setiap library Firebase seiring berjalannya waktu:
// Import stylesheets
import './style.css';
// Firebase App (the core Firebase SDK) is always required
import { initializeApp } from 'firebase/app';
// Add the Firebase products and methods that you want to use
import {} from 'firebase/auth';
import {} from 'firebase/firestore';
import * as firebaseui from 'firebaseui';
Menambahkan aplikasi web Firebase ke project Firebase
- Kembali di Firebase console, buka halaman ringkasan project Anda dengan mengklik Project Overview di kiri atas.
- Di bagian tengah halaman ringkasan project, klik ikon web untuk membuat aplikasi web Firebase baru.
- Daftarkan aplikasi dengan nama panggilan Web App.
- Untuk codelab ini, JANGAN centang kotak di samping Siapkan juga Firebase Hosting untuk aplikasi ini. Untuk saat ini, Anda akan menggunakan panel pratinjau StackBlitz.
- Klik Register app.
- Salin objek konfigurasi Firebase ke papan klip Anda.
- Klik Continue to console. Tambahkan objek konfigurasi Firebase ke aplikasi Anda:
- Kembali ke StackBlitz, buka file
index.js
. - Temukan baris komentar
Add Firebase project configuration object here
, lalu tempel cuplikan konfigurasi Anda tepat di bawah komentar. - Tambahkan panggilan fungsi
initializeApp
untuk menyiapkan Firebase menggunakan konfigurasi project Firebase unik Anda.// ... // Add Firebase project configuration object here const firebaseConfig = { apiKey: "random-unique-string", authDomain: "your-projectId.firebaseapp.com", databaseURL: "https://your-projectId.firebaseio.com", projectId: "your-projectId", storageBucket: "your-projectId.firebasestorage.app", messagingSenderId: "random-unique-string", appId: "random-unique-string", }; // Initialize Firebase initializeApp(firebaseConfig);
6. Menambahkan login pengguna (RSVP)
Setelah menambahkan Firebase ke aplikasi, Anda dapat menyiapkan tombol RSVP yang mendaftarkan orang yang menggunakan Firebase Authentication.
Mengautentikasi pengguna dengan Login dengan Email dan FirebaseUI
Anda memerlukan tombol RSVP yang meminta pengguna untuk login dengan alamat email mereka. Anda dapat melakukannya dengan menghubungkan FirebaseUI ke tombol RSVP. FirebaseUI adalah library yang memberi Anda UI bawaan di atas Firebase Auth.
FirebaseUI memerlukan konfigurasi (lihat opsi dalam dokumentasi) yang melakukan dua hal:
- Memberi tahu FirebaseUI bahwa Anda ingin menggunakan metode login Email/Sandi.
- Menangani callback untuk login yang berhasil dan menampilkan nilai salah untuk menghindari pengalihan. Anda tidak ingin halaman dimuat ulang karena Anda membuat aplikasi web satu halaman.
Menambahkan kode untuk melakukan inisialisasi FirebaseUI Auth
- Di StackBlitz, buka file
index.js
. - Di bagian atas, temukan pernyataan impor
firebase/auth
, lalu tambahkangetAuth
danEmailAuthProvider
, seperti ini:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider } from 'firebase/auth'; import {} from 'firebase/firestore';
- Simpan referensi ke objek auth tepat setelah
initializeApp
, seperti ini:initializeApp(firebaseConfig); auth = getAuth();
- Perhatikan bahwa konfigurasi FirebaseUI telah disediakan di kode awal. Aplikasi ini sudah disiapkan untuk menggunakan penyedia autentikasi email.
- Di bagian bawah fungsi
main()
diindex.js
, tambahkan pernyataan inisialisasi FirebaseUI, seperti ini:async function main() { // ... // Initialize the FirebaseUI widget using Firebase const ui = new firebaseui.auth.AuthUI(auth); } main();
Menambahkan tombol RSVP ke HTML
- Di StackBlitz, buka file
index.html
. - Tambahkan HTML untuk tombol RSVP di dalam
event-details-container
seperti yang ditunjukkan dalam contoh di bawah.
Berhati-hatilah untuk menggunakan nilaiid
yang sama seperti yang ditunjukkan di bawah karena, untuk codelab ini, sudah ada hook untuk ID spesifik ini dalam fileindex.js
.
Perhatikan bahwa dalam fileindex.html
, ada penampung dengan IDfirebaseui-auth-container
. Ini adalah ID yang akan Anda teruskan ke FirebaseUI untuk menyimpan login. Pratinjau aplikasi<!-- ... --> <section id="event-details-container"> <!-- ... --> <!-- ADD THE RSVP BUTTON HERE --> <button id="startRsvp">RSVP</button> </section> <hr> <section id="firebaseui-auth-container"></section> <!-- ... -->
- Siapkan pemroses di tombol RSVP dan panggil fungsi mulai FirebaseUI. Ini akan memberi tahu FirebaseUI bahwa Anda ingin melihat jendela login.
Tambahkan kode berikut ke bagian bawah fungsimain()
diindex.js
:async function main() { // ... // Listen to RSVP button clicks startRsvpButton.addEventListener("click", () => { ui.start("#firebaseui-auth-container", uiConfig); }); } main();
Menguji login ke aplikasi
- Di jendela pratinjau StackBlitz, klik tombol RSVP untuk login ke aplikasi.
- Untuk codelab ini, Anda dapat menggunakan alamat email apa pun, bahkan alamat email palsu, karena Anda tidak menyiapkan langkah verifikasi email untuk codelab ini.
- Jika Anda melihat pesan error yang menyatakan
auth/operation-not-allowed
atauThe given sign-in provider is disabled for this Firebase project
, pastikan Anda telah mengaktifkan Email/Sandi sebagai penyedia login di Firebase console.
- Buka dasbor Authentication di Firebase console. Di tab Pengguna, Anda akan melihat informasi akun yang Anda masukkan untuk login ke aplikasi.
Menambahkan status autentikasi ke UI
Selanjutnya, pastikan UI menunjukkan bahwa Anda telah login.
Anda akan menggunakan callback pemroses status Firebase Authentication, yang akan diberi tahu setiap kali status login pengguna berubah. Jika saat ini ada pengguna yang login, aplikasi Anda akan mengalihkan tombol "RSVP" ke tombol "logout".
- Di StackBlitz, buka file
index.js
. - Di bagian atas, temukan pernyataan impor
firebase/auth
, lalu tambahkansignOut
danonAuthStateChanged
, seperti ini:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import {} from 'firebase/firestore';
- Tambahkan kode berikut di bagian bawah fungsi
main()
:async function main() { // ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; } else { startRsvpButton.textContent = 'RSVP'; } }); } main();
- Di pemroses tombol, periksa apakah ada pengguna saat ini dan logout dari mereka. Untuk melakukannya, ganti
startRsvpButton.addEventListener
saat ini dengan kode berikut:// ... // Called when the user clicks the RSVP button startRsvpButton.addEventListener('click', () => { if (auth.currentUser) { // User is signed in; allows user to sign out signOut(auth); } else { // No user is signed in; allows user to sign in ui.start('#firebaseui-auth-container', uiConfig); } });
Sekarang, tombol di aplikasi Anda akan menampilkan LOGOUT, dan akan beralih kembali ke RSVP saat diklik.
Pratinjau aplikasi
7. Menulis pesan ke Cloud Firestore
Mengetahui bahwa pengguna akan datang adalah hal yang bagus, tetapi mari kita berikan hal lain untuk tamu di aplikasi. Bagaimana jika mereka dapat meninggalkan pesan di buku tamu? Mereka dapat menyampaikan mengapa mereka senang untuk datang atau siapa yang ingin mereka temui.
Untuk menyimpan pesan chat yang ditulis pengguna di aplikasi, Anda dapat menggunakan Cloud Firestore.
Model data
Cloud Firestore adalah database NoSQL, dan data yang disimpan di database dibagi menjadi koleksi, dokumen, kolom, dan subkoleksi. Anda akan menyimpan setiap pesan chat sebagai dokumen di koleksi level atas yang disebut guestbook
.
Menambahkan pesan ke Firestore
Di bagian ini, Anda akan menambahkan fungsi bagi pengguna untuk menulis pesan baru ke database. Pertama, Anda menambahkan HTML untuk elemen UI (kolom pesan dan tombol kirim). Kemudian, Anda menambahkan kode yang menghubungkan elemen ini ke database.
Untuk menambahkan elemen UI kolom pesan dan tombol kirim:
- Di StackBlitz, buka file
index.html
. - Temukan
guestbook-container
, lalu tambahkan HTML berikut untuk membuat formulir dengan kolom input pesan dan tombol kirim.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form id="leave-message"> <label>Leave a message: </label> <input type="text" id="message"> <button type="submit"> <i class="material-icons">send</i> <span>SEND</span> </button> </form> </section> <!-- ... -->
Pratinjau aplikasi
Pengguna yang mengklik tombol SEND akan memicu cuplikan kode di bawah. Tindakan ini akan menambahkan konten kolom input pesan ke koleksi guestbook
database. Secara khusus, metode addDoc
menambahkan konten pesan ke dokumen baru (dengan ID yang dibuat secara otomatis) ke koleksi guestbook
.
- Di StackBlitz, buka file
index.js
. - Di bagian atas, temukan pernyataan impor
firebase/firestore
, lalu tambahkangetFirestore
,addDoc
, dancollection
, seperti ini:// ... // Add the Firebase products and methods that you want to use import { getAuth, EmailAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth'; import { getFirestore, addDoc, collection } from 'firebase/firestore';
- Sekarang kita akan menyimpan referensi ke objek
db
Firestore tepat setelahinitializeApp
:initializeApp(firebaseConfig); auth = getAuth(); db = getFirestore();
- Di bagian bawah fungsi
main()
, tambahkan kode berikut.
Perlu diperhatikan bahwaauth.currentUser.uid
adalah referensi ke ID unik yang dibuat secara otomatis dan diberikan oleh Firebase Authentication untuk semua pengguna yang login.async function main() { // ... // Listen to the form submission form.addEventListener('submit', async e => { // Prevent the default form redirect e.preventDefault(); // Write a new message to the database collection "guestbook" addDoc(collection(db, 'guestbook'), { text: input.value, timestamp: Date.now(), name: auth.currentUser.displayName, userId: auth.currentUser.uid }); // clear message input field input.value = ''; // Return false to avoid redirect return false; }); } main();
Menampilkan buku tamu hanya kepada pengguna yang login
Anda tidak ingin siapa saja melihat chat tamu. Satu hal yang dapat Anda lakukan untuk mengamankan chat adalah dengan hanya mengizinkan pengguna yang login untuk melihat buku tamu. Namun, untuk aplikasi Anda sendiri, sebaiknya amankan juga database Anda dengan Aturan Keamanan Firebase. (Ada informasi selengkapnya tentang aturan keamanan nanti di codelab.)
- Di StackBlitz, buka file
index.js
. - Edit pemroses
onAuthStateChanged
untuk menyembunyikan dan menampilkan buku tamu.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; } });
Menguji pengiriman pesan
- Pastikan Anda sudah login ke aplikasi.
- Masukkan pesan seperti "Halo!", lalu klik KIRIM.
Tindakan ini akan menulis pesan ke database Cloud Firestore Anda. Namun, Anda belum akan melihat pesan di aplikasi web yang sebenarnya karena Anda masih perlu mengimplementasikan pengambilan data. Anda akan melakukannya nanti.
Namun, Anda dapat melihat pesan yang baru ditambahkan di Firebase console.
Di Firebase console, di dasbor Firestore Database, Anda akan melihat koleksi guestbook
beserta pesan yang baru ditambahkan. Jika Anda terus mengirim pesan, koleksi buku tamu Anda akan berisi banyak dokumen, seperti ini:
Firebase console
8. Membaca pesan
Menyinkronkan pesan
Sangat menyenangkan bahwa tamu dapat menulis pesan ke database, tetapi mereka belum bisa melihatnya di aplikasi.
Untuk menampilkan pesan, Anda harus menambahkan pemroses yang dipicu saat data berubah, lalu membuat elemen UI yang menampilkan pesan baru.
Anda akan menambahkan kode yang memproses pesan yang baru ditambahkan dari aplikasi. Pertama, tambahkan bagian di HTML untuk menampilkan pesan:
- Di StackBlitz, buka file
index.html
. - Di
guestbook-container
, tambahkan bagian baru dengan IDguestbook
.<!-- ... --> <section id="guestbook-container"> <h2>Discussion</h2> <form><!-- ... --></form> <section id="guestbook"></section> </section> <!-- ... -->
Selanjutnya, daftarkan pemroses yang memproses perubahan yang dibuat pada data:
- Di StackBlitz, buka file
index.js
. - Di bagian atas, temukan pernyataan impor
firebase/firestore
, lalu tambahkanquery
,orderBy
, danonSnapshot
, seperti ini:// ... import { getFirestore, addDoc, collection, query, orderBy, onSnapshot } from 'firebase/firestore';
- Di bagian bawah fungsi
main()
, tambahkan kode berikut untuk melakukan loop semua dokumen (pesan buku tamu) dalam database. Untuk mempelajari lebih lanjut tentang apa yang terjadi dalam kode ini, baca informasi di bawah cuplikan.async function main() { // ... // Create query for messages const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); } main();
Untuk memproses pesan dalam database, Anda telah membuat kueri pada koleksi tertentu menggunakan fungsi collection
. Kode di atas memproses perubahan dalam koleksi guestbook
, tempat pesan chat disimpan. Pesan juga diurutkan berdasarkan tanggal, menggunakan orderBy('timestamp', 'desc')
untuk menampilkan pesan terbaru di bagian atas.
Fungsi onSnapshot
menggunakan dua parameter: kueri yang akan digunakan dan fungsi callback. Fungsi callback dipicu saat ada perubahan pada dokumen yang cocok dengan kueri. Hal ini dapat terjadi jika pesan dihapus, diubah, atau ditambahkan. Untuk mengetahui informasi selengkapnya, lihat dokumentasi Cloud Firestore.
Menguji sinkronisasi pesan
Cloud Firestore otomatis dan langsung menyinkronkan data dengan klien yang berlangganan database.
- Pesan yang Anda buat sebelumnya di database akan ditampilkan di aplikasi. Jangan ragu untuk menulis pesan baru; pesan tersebut akan langsung muncul.
- Jika Anda membuka ruang kerja di beberapa jendela atau tab, pesan akan disinkronkan secara real time di seluruh tab.
- (Opsional) Anda dapat mencoba menghapus, mengubah, atau menambahkan pesan baru secara manual secara langsung di bagian Database pada Firebase console; setiap perubahan akan muncul di UI.
Selamat! Anda sedang membaca dokumen Cloud Firestore di aplikasi.
Pratinjau aplikasi
9. Menyiapkan aturan keamanan dasar
Pertama-tama, Anda menyiapkan Cloud Firestore untuk menggunakan mode pengujian, yang berarti bahwa database Anda terbuka untuk pembacaan dan penulisan. Namun, Anda hanya boleh menggunakan mode pengujian selama tahap awal pengembangan. Sebagai praktik terbaik, Anda harus menyiapkan aturan keamanan untuk database saat mengembangkan aplikasi. Keamanan harus menjadi bagian integral dari struktur dan perilaku aplikasi.
Aturan Keamanan memungkinkan Anda mengontrol akses ke dokumen dan koleksi di database. Dengan sintaksis aturan yang fleksibel, Anda dapat membuat aturan yang cocok dengan apa pun, dari semua penulisan ke seluruh database hingga operasi pada dokumen tertentu.
Anda dapat menulis aturan keamanan untuk Cloud Firestore di Firebase console:
- Di bagian Build Firebase console, klik Firestore Database, lalu pilih tab Rules (atau klik di sini untuk langsung membuka tab Rules).
- Anda akan melihat aturan keamanan default berikut, dengan batas waktu akses publik beberapa minggu dari sekarang.
Mengidentifikasi koleksi
Pertama, identifikasi koleksi tempat aplikasi menulis data.
- Hapus klausa
match /{document=**}
yang ada, sehingga aturan Anda terlihat seperti ini:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { } }
- Di
match /databases/{database}/documents
, identifikasi koleksi yang ingin Anda amankan:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { // You'll add rules here in the next step. } }
Tambahkan aturan keamanan
Karena Anda menggunakan UID Autentikasi sebagai kolom di setiap dokumen buku tamu, Anda bisa mendapatkan UID Autentikasi dan memverifikasi bahwa siapa pun yang mencoba menulis ke dokumen memiliki UID Autentikasi yang cocok.
- Tambahkan aturan baca dan tulis ke kumpulan aturan Anda seperti yang ditunjukkan di bawah:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId; } } }
- Klik Publikasikan untuk men-deploy aturan baru Anda. Sekarang, untuk buku tamu, hanya pengguna yang login yang dapat membaca pesan (pesan apa pun), tetapi Anda hanya dapat membuat pesan menggunakan ID pengguna Anda. Kami juga tidak mengizinkan pesan untuk diedit atau dihapus.
Menambahkan aturan validasi
- Tambahkan validasi data untuk memastikan semua kolom yang diharapkan ada dalam dokumen:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { allow read: if request.auth.uid != null; allow create: if request.auth.uid == request.resource.data.userId && "name" in request.resource.data && "text" in request.resource.data && "timestamp" in request.resource.data; } } }
- Klik Publikasikan untuk men-deploy aturan baru Anda.
Mereset pemroses
Karena aplikasi Anda kini hanya mengizinkan pengguna yang diautentikasi untuk login, Anda harus memindahkan kueri firestore
buku tamu ke dalam pemroses Autentikasi. Jika tidak, error izin akan terjadi dan aplikasi akan terputus saat pengguna logout.
- Di StackBlitz, buka file
index.js
. - Tarik pemroses
onSnapshot
koleksi buku tamu ke dalam fungsi baru yang disebutsubscribeGuestbook
. Selain itu, tetapkan hasil fungsionSnapshot
ke variabelguestbookListener
.
PemrosesonSnapshot
Firestore menampilkan fungsi berhenti berlangganan yang dapat Anda gunakan untuk membatalkan pemroses snapshot nanti.// ... // Listen to guestbook updates function subscribeGuestbook() { const q = query(collection(db, 'guestbook'), orderBy('timestamp', 'desc')); guestbookListener = onSnapshot(q, snaps => { // Reset page guestbook.innerHTML = ''; // Loop through documents in database snaps.forEach(doc => { // Create an HTML entry for each document and add it to the chat const entry = document.createElement('p'); entry.textContent = doc.data().name + ': ' + doc.data().text; guestbook.appendChild(entry); }); }); }
- Tambahkan fungsi baru di bawahnya yang disebut
unsubscribeGuestbook
. Periksa apakah variabelguestbookListener
bukan null, lalu panggil fungsi untuk membatalkan pemroses.// ... // Unsubscribe from guestbook updates function unsubscribeGuestbook() { if (guestbookListener != null) { guestbookListener(); guestbookListener = null; } }
Terakhir, tambahkan fungsi baru ke callback onAuthStateChanged
.
- Tambahkan
subscribeGuestbook()
di bagian bawahif (user)
. - Tambahkan
unsubscribeGuestbook()
di bagian bawah pernyataanelse
.// ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none'; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); } });
10. Langkah bonus: Praktikkan apa yang telah Anda pelajari
Mencatat status RSVP peserta
Saat ini, aplikasi Anda hanya mengizinkan orang untuk mulai melakukan chat jika mereka tertarik dengan acara tersebut. Selain itu, satu-satunya cara untuk mengetahui apakah seseorang akan hadir adalah jika mereka mempostingnya di chat. Mari kita atur dan beri tahu orang-orang berapa banyak orang yang akan datang.
Anda akan menambahkan tombol untuk mendaftarkan orang yang ingin menghadiri acara, lalu mengumpulkan jumlah orang yang akan datang.
- Di StackBlitz, buka file
index.html
. - Di
guestbook-container
, tambahkan sekumpulan tombol YES dan NO, seperti ini:<!-- ... --> <section id="guestbook-container"> <h2>Are you attending?</h2> <button id="rsvp-yes">YES</button> <button id="rsvp-no">NO</button> <h2>Discussion</h2> <!-- ... --> </section> <!-- ... -->
Pratinjau aplikasi
Selanjutnya, daftarkan pemroses untuk klik tombol. Jika pengguna mengklik YA, gunakan UID Autentikasi mereka untuk menyimpan respons ke database.
- Di StackBlitz, buka file
index.js
. - Di bagian atas, temukan pernyataan impor
firebase/firestore
, lalu tambahkandoc
,setDoc
, danwhere
, seperti ini:// ... // Add the Firebase products and methods that you want to use import { getFirestore, addDoc, collection, query, orderBy, onSnapshot, doc, setDoc, where } from 'firebase/firestore';
- Di bagian bawah fungsi
main()
, tambahkan kode berikut untuk memproses status RSVP:async function main() { // ... // Listen to RSVP responses rsvpYes.onclick = async () => { }; rsvpNo.onclick = async () => { }; } main();
- Selanjutnya, buat koleksi baru bernama
attendees
, lalu daftarkan referensi dokumen jika salah satu tombol RSVP diklik. Tetapkan referensi tersebut ketrue
ataufalse
, bergantung pada tombol yang diklik.
Pertama, untukrsvpYes
: Kemudian, hal yang sama berlaku untuk// ... // Listen to RSVP responses rsvpYes.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attendi()ng: true try { await setDoc(userRef, { attending: true }); } catch (e) { console.error(e); } };
rsvpNo
, tetapi dengan nilaifalse
:rsvpNo.onclick = async () => { // Get a reference to the user's document in the attendees collection const userRef = doc(db, 'attendees', auth.currentUser.uid); // If they RSVP'd yes, save a document with attending: true try { await setDoc(userRef, { attending: false }); } catch (e) { console.error(e); } };
Memperbarui Aturan Keamanan
Karena Anda sudah menyiapkan beberapa aturan, data baru yang Anda tambahkan dengan tombol akan ditolak.
Mengizinkan penambahan ke koleksi attendees
Anda harus memperbarui aturan untuk mengizinkan penambahan ke kumpulan attendees
.
- Untuk koleksi
attendees
, karena Anda menggunakan UID Autentikasi sebagai nama dokumen, Anda dapat mengambilnya dan memverifikasi bahwauid
pengirim sama dengan dokumen yang mereka tulis. Anda akan mengizinkan semua orang membaca daftar peserta (karena tidak ada data pribadi di sana), tetapi hanya kreator yang dapat memperbaruinya.rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId; } } }
- Klik Publikasikan untuk men-deploy aturan baru.
Menambahkan aturan validasi
- Tambahkan beberapa aturan validasi data untuk memastikan semua kolom yang diharapkan ada dalam dokumen:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // ... // match /attendees/{userId} { allow read: if true; allow write: if request.auth.uid == userId && "attending" in request.resource.data; } } }
- Jangan lupa klik Publikasikan untuk men-deploy aturan Anda.
(Opsional) Sekarang Anda dapat melihat hasil mengklik tombol. Buka dasbor Cloud Firestore di Firebase console.
Membaca status RSVP
Setelah Anda merekam respons, mari kita lihat siapa yang datang dan tampilkan di UI.
- Di StackBlitz, buka file
index.html
. - Di
description-container
, tambahkan elemen baru dengan IDnumber-attending
.<!-- ... --> <section id="description-container"> <!-- ... --> <p id="number-attending"></p> </section> <!-- ... -->
Selanjutnya, daftarkan pemroses untuk koleksi attendees
dan hitung jumlah respons YES:
- Di StackBlitz, buka file
index.js
. - Di bagian bawah fungsi
main()
, tambahkan kode berikut untuk memproses status RSVP dan menghitung klik YA.async function main() { // ... // Listen for attendee list const attendingQuery = query( collection(db, 'attendees'), where('attending', '==', true) ); const unsubscribe = onSnapshot(attendingQuery, snap => { const newAttendeeCount = snap.docs.length; numberAttending.innerHTML = newAttendeeCount + ' people going'; }); } main();
Terakhir, mari kita soroti tombol yang sesuai dengan status saat ini.
- Buat fungsi yang memeriksa apakah UID Autentikasi saat ini memiliki entri dalam koleksi
attendees
, lalu setel class tombol keclicked
.// ... // Listen for attendee list function subscribeCurrentRSVP(user) { const ref = doc(db, 'attendees', user.uid); rsvpListener = onSnapshot(ref, doc => { if (doc && doc.data()) { const attendingResponse = doc.data().attending; // Update css classes for buttons if (attendingResponse) { rsvpYes.className = 'clicked'; rsvpNo.className = ''; } else { rsvpYes.className = ''; rsvpNo.className = 'clicked'; } } }); }
- Selain itu, mari kita buat fungsi untuk berhenti berlangganan. Ini akan digunakan saat pengguna logout.
// ... function unsubscribeCurrentRSVP() { if (rsvpListener != null) { rsvpListener(); rsvpListener = null; } rsvpYes.className = ''; rsvpNo.className = ''; }
- Panggil fungsi dari pemroses Authentication.
// ... // Listen to the current Auth state // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; // Show guestbook to logged-in users guestbookContainer.style.display = 'block'; // Subscribe to the guestbook collection subscribeGuestbook(); // Subscribe to the user's RSVP subscribeCurrentRSVP(user); } else { startRsvpButton.textContent = 'RSVP'; // Hide guestbook for non-logged-in users guestbookContainer.style.display = 'none' ; // Unsubscribe from the guestbook collection unsubscribeGuestbook(); // Unsubscribe from the guestbook collection unsubscribeCurrentRSVP(); } });
- Coba login sebagai beberapa pengguna dan lihat jumlah yang bertambah dengan setiap klik tombol YA tambahan.
Pratinjau aplikasi
11. Selamat!
Anda telah menggunakan Firebase untuk membuat aplikasi web interaktif dan real-time.
Yang telah kita bahas
- Firebase Authentication
- FirebaseUI
- Cloud Firestore
- Aturan Keamanan Firebase
Langkah berikutnya
- Ingin mempelajari lebih lanjut Alur Kerja Developer Firebase? Lihat codelab emulator Firebase untuk mempelajari cara menguji dan menjalankan aplikasi sepenuhnya secara lokal.
- Ingin mempelajari produk Firebase lainnya lebih lanjut? Mungkin Anda ingin menyimpan file gambar yang diupload pengguna? Atau mengirim notifikasi kepada pengguna? Lihat codelab web Firebase untuk mengetahui codelab yang membahas lebih mendalam tentang banyak produk Firebase lainnya untuk web.
- Ingin mempelajari Cloud Firestore lebih lanjut? Mungkin Anda ingin mempelajari subkoleksi dan transaksi? Buka codelab web Cloud Firestore untuk mempelajari codelab secara lebih mendalam tentang Cloud Firestore. Atau lihat serial YouTube ini untuk mengenal Cloud Firestore.
Pelajari lebih lanjut
- Situs Firebase: firebase.google.com
- Channel YouTube Firebase
Bagaimana hasilnya?
Kami ingin mendengar masukan dari Anda. Harap isi formulir (sangat) singkat di sini.