Codelab Framework Web Angular Firebase

1. Yang akan Anda buat

Dalam codelab ini, Anda akan membangun blog perjalanan dengan peta kolaboratif real-time dengan yang terbaru dari library Angular kami: AngularFire. Aplikasi web final akan terdiri dari blog perjalanan tempat Anda dapat mengupload gambar ke setiap lokasi yang telah Anda kunjungi.

AngularFire akan digunakan untuk membangun aplikasi web, Emulator Suite untuk pengujian lokal, Authentication untuk melacak data pengguna, Firestore dan Storage untuk mempertahankan data dan media, didukung oleh Cloud Functions, dan terakhir, Firebase Hosting untuk men-deploy aplikasi.

Yang akan Anda pelajari

  • Cara mengembangkan aplikasi dengan produk Firebase secara lokal dengan Emulator Suite
  • Cara meningkatkan kualitas aplikasi web dengan AngularFire
  • Cara mempertahankan data Anda di Firestore
  • Cara mempertahankan media di Storage
  • Cara men-deploy aplikasi Anda ke Firebase Hosting
  • Cara menggunakan Cloud Functions untuk berinteraksi dengan database dan API Anda

Yang Anda butuhkan

  • Node.js versi 10 atau yang lebih baru
  • Akun Google untuk pembuatan dan pengelolaan Project Firebase Anda
  • Firebase CLI versi 11.14.2 atau yang lebih baru
  • Browser pilihan Anda, seperti Chrome
  • Pemahaman dasar tentang Angular dan JavaScript

2. Mendapatkan kode contoh

Clone repositori GitHub codelab dari command line:

git clone https://github.com/firebase/codelab-friendlychat-web

Atau, jika belum menginstal git, Anda dapat mendownload repositori sebagai file ZIP.

Repositori GitHub berisi project contoh untuk berbagai platform.

Codelab ini hanya menggunakan repositori webframework:

  • 🪄 webframework: Kode awal yang akan Anda bangun selama codelab ini.

Menginstal dependensi

Setelah melakukan cloning, instal dependensi di root dan folder functions sebelum membangun aplikasi web.

cd webframework && npm install
cd functions && npm install

Instal Firebase CLI

Instal Firebase CLI menggunakan perintah ini di terminal:

npm install -g firebase-tools

Periksa kembali apakah versi Firebase CLI Anda lebih tinggi dari 11.14.2 menggunakan:

firebase  --version

Jika versi Anda lebih rendah dari 11.14.2, harap update menggunakan:

npm update firebase-tools

3. Membuat dan menyiapkan project Firebase

Membuat project Firebase

  1. Login ke Firebase.
  2. Di Firebase console, klik Tambahkan Project, lalu beri nama project Firebase Anda <your-project>. Ingat ID project untuk project Firebase Anda.
  3. Klik Buat Project.

Penting: Project Firebase Anda akan diberi nama <your-project>, tetapi Firebase akan otomatis memberinya Project ID unik dalam bentuk <your-project>-1234. Project Anda akan diidentifikasi dengan ID unik ini (termasuk di CLI), sedangkan <your-project> hanyalah nama tampilan.

Aplikasi yang akan kita bangun menggunakan produk Firebase yang tersedia untuk aplikasi web:

  • Firebase Authentication untuk memudahkan pengguna login ke aplikasi Anda.
  • Cloud Firestore untuk menyimpan data terstruktur di cloud dan mendapatkan notifikasi instan saat data berubah.
  • Cloud Storage for Firebase untuk menyimpan file di cloud.
  • Firebase Hosting untuk menghosting dan menayangkan aset Anda.
  • Fungsi untuk berinteraksi dengan API internal dan eksternal.

Beberapa produk ini memerlukan konfigurasi khusus atau perlu diaktifkan menggunakan Firebase console.

Menambahkan aplikasi web Firebase ke project

  1. Klik ikon web untuk membuat aplikasi web Firebase baru.
  2. Pada langkah berikutnya, Anda akan melihat objek konfigurasi. Salin konten objek ini ke dalam file environments/environment.ts.

Aktifkan login untuk Firebase Authentication dengan Google

Untuk mengizinkan pengguna login ke aplikasi web dengan Akun Google mereka, kami akan menggunakan metode login Google.

Untuk mengaktifkan login dengan Google:

  1. Di Firebase console, cari bagian Build di panel kiri.
  2. Klik Autentikasi, lalu klik tab Metode login (atau klik di sini untuk langsung membukanya).
  3. Aktifkan penyedia login Google, lalu klik Simpan.
  4. Tetapkan nama aplikasi yang ditampilkan kepada publik ke <your-project-name> dan pilih Project support email dari menu dropdown.

Mengaktifkan Cloud Firestore

  1. Di bagian Build Firebase console, klik Firestore Database.
  2. Klik Buat database di panel Cloud Firestore.
  3. Tetapkan lokasi penyimpanan data Cloud Firestore Anda. Anda dapat membiarkannya sebagai default atau memilih region yang dekat dengan Anda.

Mengaktifkan Cloud Storage

Aplikasi web menggunakan Cloud Storage for Firebase untuk menyimpan, mengupload, dan membagikan gambar.

  1. Di bagian Build Firebase console, klik Storage.
  2. Jika tidak ada tombol Mulai, artinya Cloud Storage sudah

diaktifkan, dan Anda tidak perlu mengikuti langkah-langkah di bawah.

  1. Klik Mulai.
  2. Baca pernyataan penyangkalan tentang aturan keamanan untuk project Firebase Anda, lalu klik Next.
  3. Lokasi Cloud Storage telah dipilih sebelumnya dengan region yang sama dengan yang Anda pilih untuk database Cloud Firestore. Klik Selesai untuk menyelesaikan penyiapan.

Dengan aturan keamanan default, setiap pengguna terautentikasi dapat menulis apa pun ke Cloud Storage. Kita akan membuat penyimpanan lebih aman nanti di codelab ini.

4. Menghubungkan ke project Firebase Anda

Antarmuka command line (CLI) Firebase memungkinkan Anda menggunakan Firebase Hosting untuk menayangkan aplikasi web secara lokal, serta men-deploy aplikasi web ke project Firebase.

Pastikan command line mengakses direktori webframework lokal aplikasi Anda.

Hubungkan kode aplikasi web ke project Firebase Anda. Pertama, login ke Firebase CLI di command line:

firebase login

Selanjutnya, jalankan perintah berikut untuk membuat alias project. Ganti $YOUR_PROJECT_ID dengan ID project Firebase Anda.

firebase  use  $YOUR_PROJECT_ID

Menambahkan AngularFire

Untuk menambahkan AngularFire ke aplikasi, jalankan perintah:

ng add @angular/fire

Kemudian, ikuti petunjuk command line, dan pilih fitur yang ada di project Firebase Anda.

Melakukan inisialisasi Firebase

Untuk melakukan inisialisasi project Firebase, jalankan:

firebase init

Kemudian, dengan mengikuti prompt command line, pilih fitur dan emulator yang digunakan di project Firebase Anda.

Memulai emulator

Dari direktori webframework, jalankan perintah berikut untuk memulai emulator:

firebase  emulators:start

Pada akhirnya, Anda akan melihat tampilan seperti ini:

$  firebase  emulators:start

i  emulators:  Starting  emulators:  auth,  functions,  firestore,  hosting,  functions

i  firestore:  Firestore  Emulator  logging  to  firestore-debug.log

i  hosting:  Serving  hosting  files  from:  public

  hosting:  Local  server:  http://localhost:5000

i  ui:  Emulator  UI  logging  to  ui-debug.log

i  functions:  Watching  "/functions"  for  Cloud  Functions...

  functions[updateMap]:  firestore  function  initialized.

  

┌─────────────────────────────────────────────────────────────┐

    All  emulators  ready!  It  is  now  safe  to  connect  your  app.  

  i  View  Emulator  UI  at  http://localhost:4000  

└─────────────────────────────────────────────────────────────┘

  

┌────────────────┬────────────────┬─────────────────────────────────┐

  Emulator    Host:Port    View  in  Emulator  UI  

├────────────────┼────────────────┼─────────────────────────────────┤

  Authentication    localhost:9099    http://localhost:4000/auth  

├────────────────┼────────────────┼─────────────────────────────────┤

  Functions    localhost:5001    http://localhost:4000/functions  

├────────────────┼────────────────┼─────────────────────────────────┤

  Firestore    localhost:8080    http://localhost:4000/firestore  

├────────────────┼────────────────┼─────────────────────────────────┤

  Hosting    localhost:5000    n/a  

└────────────────┴────────────────┴─────────────────────────────────┘

Emulator  Hub  running  at  localhost:4400

Other  reserved  ports:  4500

  

Issues?  Report  them  at  https://github.com/firebase/firebase-tools/issues  and  attach  the  *-debug.log  files.

Setelah Anda melihat pesan ✔All emulators ready!, emulator siap digunakan.

Anda akan melihat UI aplikasi perjalanan yang (belum) berfungsi:

Sekarang mari membangun!

5. Menghubungkan aplikasi web ke emulator

Berdasarkan tabel dalam log emulator, emulator Cloud Firestore memproses port 8080 dan emulator Authentication memproses port 9099.

Membuka EmulatorUI

Di browser web, buka http://127.0.0.1:4000/. Anda akan melihat UI Emulator Suite.

Merutekan aplikasi untuk menggunakan emulator

Di src/app/app.module.ts, tambahkan kode berikut ke daftar impor AppModule:

@NgModule({
	declarations: [...],
	imports: [
		provideFirebaseApp(() =>  initializeApp(environment.firebase)),

		provideAuth(() => {
			const  auth = getAuth();
			if (location.hostname === 'localhost') {
				connectAuthEmulator(auth, 'http://127.0.0.1:9099', { disableWarnings:  true });
			}
			return  auth;
		}),

		provideFirestore(() => {
			const  firestore = getFirestore();
			if (location.hostname === 'localhost') {
				connectFirestoreEmulator(firestore, '127.0.0.1', 8080);
			}
			return  firestore;
		}),

		provideFunctions(() => {
			const  functions = getFunctions();
			if (location.hostname === 'localhost') {
				connectFunctionsEmulator(functions, '127.0.0.1', 5001);
			}
			return  functions;
		}),

		provideStorage(() => {
			const  storage = getStorage();
			if (location.hostname === 'localhost') {
				connectStorageEmulator(storage, '127.0.0.1', 5001);
			}
			return  storage;
		}),
		...
	]

Aplikasi sekarang dikonfigurasi untuk menggunakan emulator lokal, sehingga pengujian dan pengembangan dilakukan secara lokal.

6. Menambahkan Autentikasi

Setelah emulator disiapkan untuk aplikasi, kita dapat menambahkan fitur Autentikasi untuk memastikan setiap pengguna login sebelum memposting pesan.

Untuk melakukannya, kita dapat mengimpor fungsi signin langsung dari AngularFire, dan melacak status autentikasi pengguna dengan fungsi authState. Ubah fungsi halaman login agar halaman memeriksa status autentikasi pengguna saat dimuat.

Memasukkan Autentikasi AngularFire

Di src/app/pages/login-page/login-page.component.ts, impor Auth dari @angular/fire/auth, dan masukkan ke dalam LoginPageComponent. Penyedia autentikasi, seperti Google, dan fungsi seperti signin, signout juga dapat diimpor langsung dari paket yang sama, dan digunakan dalam aplikasi.

import { Auth, GoogleAuthProvider, signInWithPopup, signOut, user } from  '@angular/fire/auth';

export  class  LoginPageComponent  implements  OnInit {
	private  auth: Auth = inject(Auth);
	private  provider = new  GoogleAuthProvider();
	user$ = user(this.auth);
	constructor() {}  

	ngOnInit(): void {} 

	login() {
		signInWithPopup(this.auth, this.provider).then((result) => {
			const  credential = GoogleAuthProvider.credentialFromResult(result);
			return  credential;
		})
	}

	logout() {
		signOut(this.auth).then(() => {
			console.log('signed out');}).catch((error) => {
				console.log('sign out error: ' + error);
		})
	}
}

Sekarang halaman login sudah berfungsi. Coba login, dan lihat hasilnya di Emulator Authentication.

7. Mengonfigurasi Firestore

Pada langkah ini, Anda akan menambahkan fungsi untuk memposting dan memperbarui postingan blog perjalanan yang disimpan di Firestore.

Serupa dengan Authentication, fungsi Firestore sudah dikemas dari AngularFire. Setiap dokumen termasuk dalam koleksi, dan setiap dokumen juga dapat memiliki koleksi bertingkat. Mengetahui path dokumen di Firestore diperlukan untuk membuat dan memperbarui postingan blog perjalanan.

Menerapkan TravelService

Karena banyak halaman yang berbeda yang perlu membaca dan memperbarui dokumen Firestore di aplikasi web, kita dapat menerapkan fungsi di src/app/services/travel.service.ts, untuk menghindari memasukkan fungsi AngularFire yang sama berulang kali di setiap halaman.

Mulai dengan memasukkan Auth, mirip dengan langkah sebelumnya, serta Firestore ke dalam layanan kita. Menentukan objek user$ yang dapat diamati yang memproses status autentikasi saat ini juga berguna.

import { doc, docData, DocumentReference, Firestore, getDoc, setDoc, updateDoc, collection, addDoc, deleteDoc, collectionData, Timestamp } from  "@angular/fire/firestore";

export  class  TravelService {
	firestore: Firestore = inject(Firestore);
	auth: Auth = inject(Auth);
	user$ = authState(this.auth).pipe(filter(user  =>  user !== null), map(user  =>  user!));
	router: Router = inject(Router);

Menambahkan postingan perjalanan

Postingan perjalanan akan ada sebagai dokumen yang disimpan di Firestore. Karena dokumen harus ada dalam koleksi, koleksi yang berisi semua postingan perjalanan akan diberi nama travels. Dengan demikian, jalur postingan perjalanan akan menjadi travels/

Dengan menggunakan fungsi addDoc dari AngularFire, objek dapat disisipkan ke dalam koleksi:

async  addEmptyTravel(userId: String) {
	...
	addDoc(collection(this.firestore, 'travels'), travelData).then((travelRef) => {
		collection(this.firestore, `travels/${travelRef.id}/stops`);
		setDoc(travelRef, {... travelData, id:  travelRef.id})
		this.router.navigate(['edit', `${travelRef.id}`]);
		return  travelRef;

	})
}

Memperbarui dan menghapus data

Dengan UID dari setiap postingan perjalanan, kita dapat menyimpulkan jalur dokumen yang disimpan di Firestore, yang kemudian dapat dibaca, diperbarui, atau dihapus menggunakan fungsi updateFoc dan deleteDoc AngularFire:

async  updateData(path: string, data: Partial<Travel | Stop>) {
	await  updateDoc(doc(this.firestore, path), data)
}

async  deleteData(path: string) {
	const  ref = doc(this.firestore, path);
	await  deleteDoc(ref)
}

Membaca data sebagai hal yang dapat diamati

Karena postingan dan perhentian perjalanan di sepanjang jalan dapat diubah setelah dibuat, akan lebih berguna untuk mendapatkan objek dokumen sebagai dapat diamati, untuk berlangganan perubahan apa pun yang dibuat. Fungsi ini ditawarkan oleh fungsi docData dan collectionData dari @angular/fire/firestore.

getDocData(path: string) {
	return  docData(doc(this.firestore, path), {idField:  'id'}) as  Observable<Travel | Stop>
}

  
getCollectionData(path: string) {
	return  collectionData(collection(this.firestore, path), {idField:  'id'}) as  Observable<Travel[] | Stop[]>
}

Menambahkan perhentian ke postingan perjalanan

Setelah operasi postingan perjalanan disiapkan, saatnya mempertimbangkan perhentian, yang akan ada di subkoleksi postingan perjalanan seperti ini: travels//stops/

Hampir mirip dengan membuat postingan perjalanan, jadi tantang diri Anda untuk menerapkannya sendiri, atau lihat penerapan di bawah ini:

async  addStop(travelId: string) {
	...
	const  ref = await  addDoc(collection(this.firestore, `travels/${travelId}/stops`), stopData)
	setDoc(ref, {...stopData, id:  ref.id})
}

Bagus! Fungsi Firestore telah diterapkan di layanan Perjalanan, sehingga sekarang Anda dapat melihat cara kerjanya.

Menggunakan fungsi Firestore di aplikasi

Buka src/app/pages/my-travels/my-travels.component.ts dan masukkan TravelService untuk menggunakan fungsinya.

travelService = inject(TravelService);
travelsData$: Observable<Travel[]>;
stopsList$!: Observable<Stop[]>;
constructor() {
	this.travelsData$ = this.travelService.getCollectionData(`travels`) as  Observable<Travel[]>
}

TravelService dipanggil dalam konstruktor untuk mendapatkan array Observable dari semua perjalanan.

Jika hanya perjalanan pengguna saat ini yang diperlukan, gunakan fungsi query.

Metode lain untuk memastikan keamanan mencakup penerapan aturan keamanan, atau menggunakan Cloud Functions dengan Firestore seperti yang dibahas dalam langkah opsional di bawah

Kemudian, cukup panggil fungsi yang diterapkan di TravelService.

async  createTravel(userId: String) {
	this.travelService.addEmptyTravel(userId);
}

deleteTravel(travelId: String) {
	this.travelService.deleteData(`travels/${travelId}`)
}

Sekarang halaman Perjalanan Saya seharusnya sudah berfungsi. Lihat apa yang terjadi di emulator Firestore saat Anda membuat postingan perjalanan baru.

Kemudian, ulangi untuk fungsi pembaruan di /src/app/pages/edit-travels/edit-travels.component.ts:

travelService: TravelService = inject(TravelService)
travelId = this.activatedRoute.snapshot.paramMap.get('travelId');
travelData$: Observable<Travel>;
stopsData$: Observable<Stop[]>;

constructor() {
	this.travelData$ = this.travelService.getDocData(`travels/${this.travelId}`) as  Observable<Travel>
	this.stopsData$ = this.travelService.getCollectionData(`travels/${this.travelId}/stops`) as  Observable<Stop[]>
}

updateCurrentTravel(travel: Partial<Travel>) {
	this.travelService.updateData(`travels${this.travelId}`, travel)
}

  

updateCurrentStop(stop: Partial<Stop>) {
	stop.type = stop.type?.toString();
	this.travelService.updateData(`travels${this.travelId}/stops/${stop.id}`, stop)
}

  

addStop() {
	if (!this.travelId) return;
	this.travelService.addStop(this.travelId);
}

deleteStop(stopId: string) {
	if (!this.travelId || !stopId) {
		return;
	}
	this.travelService.deleteData(`travels${this.travelId}/stops/${stopId}`)
	this.stopsData$ = this.travelService.getCollectionData(`travels${this.travelId}/stops`) as  Observable<Stop[]>

}

8. Mengonfigurasi Penyimpanan

Sekarang Anda akan mengimplementasikan Storage untuk menyimpan gambar dan jenis media lainnya.

Cloud Firestore paling cocok digunakan untuk menyimpan data terstruktur, seperti objek JSON. Cloud Storage dirancang untuk menyimpan file atau blob. Di aplikasi ini, Anda akan menggunakannya untuk memungkinkan pengguna membagikan foto perjalanan mereka.

Demikian pula dengan Firestore, penyimpanan dan pembaruan file dengan Storage memerlukan ID unik untuk setiap file.

Mari kita implementasikan fungsi di TraveService:

Mengupload file

Buka src/app/services/travel.service.ts dan masukkan Storage dari AngularFire:

export  class  TravelService {
firestore: Firestore = inject(Firestore);
auth: Auth = inject(Auth);
storage: Storage = inject(Storage);

Dan implementasikan fungsi upload:

async  uploadToStorage(path: string, input: HTMLInputElement, contentType: any) {
	if (!input.files) return  null
	const  files: FileList = input.files;
		for (let  i = 0; i  <  files.length; i++) {
			const  file = files.item(i);
			if (file) {
				const  imagePath = `${path}/${file.name}`
				const  storageRef = ref(this.storage, imagePath);
				await  uploadBytesResumable(storageRef, file, contentType);
				return  await  getDownloadURL(storageRef);
			}
		}
	return  null;
}

Perbedaan utama antara mengakses dokumen dari Firestore dan file dari Cloud Storage adalah, meskipun keduanya mengikuti jalur terstruktur folder, kombinasi URL dasar dan jalur diperoleh melalui getDownloadURL, yang kemudian dapat disimpan, dan digunakan dalam file .

Menggunakan fungsi di aplikasi

Buka src/app/components/edit-stop/edit-stop.component.ts dan panggil fungsi upload menggunakan:

	async  uploadFile(file: HTMLInputElement, stop: Partial<Stop>) {
	const  path = `/travels/${this.travelId}/stops/${stop.id}`
	const  url = await  this.travelService.uploadToStorage(path, file, {contentType:  'image/png'});
	stop.image = url ? url : '';
	this.travelService.updateData(path, stop);
}

Saat gambar diupload, file media itu sendiri akan diupload ke penyimpanan, dan URL-nya disimpan sesuai dengan dokumen di Firestore.

9. Men-deploy aplikasi

Sekarang kita siap men-deploy aplikasi.

Salin konfigurasi firebase dari src/environments/environment.ts ke src/environments/environment.prod.ts dan jalankan:

firebase deploy

Anda akan melihat sesuatu seperti ini:

 Browser application bundle generation complete.
 Copying assets complete.
 Index html generation complete.

=== Deploying to 'friendly-travels-b6a4b'...

i  deploying storage, firestore, hosting
i  firebase.storage: checking storage.rules for compilation errors...
  firebase.storage: rules file storage.rules compiled successfully
i  firestore: reading indexes from firestore.indexes.json...
i  cloud.firestore: checking firestore.rules for compilation errors...
  cloud.firestore: rules file firestore.rules compiled successfully
i  storage: latest version of storage.rules already up to date, skipping upload...
i  firestore: deploying indexes...
i  firestore: latest version of firestore.rules already up to date, skipping upload...
  firestore: deployed indexes in firestore.indexes.json successfully for (default) database
i  hosting[friendly-travels-b6a4b]: beginning deploy...
i  hosting[friendly-travels-b6a4b]: found 6 files in .firebase/friendly-travels-b6a4b/hosting
  hosting[friendly-travels-b6a4b]: file upload complete
  storage: released rules storage.rules to firebase.storage
  firestore: released rules firestore.rules to cloud.firestore
i  hosting[friendly-travels-b6a4b]: finalizing version...
  hosting[friendly-travels-b6a4b]: version finalized
i  hosting[friendly-travels-b6a4b]: releasing new version...
  hosting[friendly-travels-b6a4b]: release complete

  Deploy complete!

Project Console: https://console.firebase.google.com/project/friendly-travels-b6a4b/overview
Hosting URL: https://friendly-travels-b6a4b.web.app

10. Selamat!

Sekarang aplikasi Anda sudah selesai dan di-deploy ke Firebase Hosting. Semua data dan analisis kini dapat diakses di Firebase Console.

Untuk fitur lainnya terkait AngularFire, Functions, dan aturan keamanan, jangan lupa untuk melihat langkah-langkah opsional di bawah ini, serta Codelab Firebase lainnya.

11. Opsional: Penjaga autentikasi AngularFire

Bersama dengan Firebase Authentication, AngularFire juga menawarkan perlindungan berbasis autentikasi pada rute, sehingga pengguna yang tidak memiliki akses dapat dialihkan. Hal ini membantu melindungi aplikasi dari pengguna yang mengakses data terlindungi.

Di src/app/app-routing.module.ts, impor

import {AuthGuard, redirectLoggedInTo, redirectUnauthorizedTo} from  '@angular/fire/auth-guard'

Kemudian, Anda dapat menentukan fungsi terkait kapan dan ke mana pengguna akan dialihkan di halaman tertentu:

const  redirectUnauthorizedToLogin = () =>  redirectUnauthorizedTo(['signin']);
const  redirectLoggedInToTravels = () =>  redirectLoggedInTo(['my-travels']);

Kemudian, cukup tambahkan ke rute Anda:

const  routes: Routes = [
	{path:  '', component:  LoginPageComponent, canActivate: [AuthGuard], data: {authGuardPipe:  redirectLoggedInToTravels}},
	{path:  'signin', component:  LoginPageComponent, canActivate: [AuthGuard], data: {authGuardPipe:  redirectLoggedInToTravels}},
	{path:  'my-travels', component:  MyTravelsComponent, canActivate: [AuthGuard], data: {authGuardPipe:  redirectUnauthorizedToLogin}},
	{path:  'edit/:travelId', component:  EditTravelsComponent, canActivate: [AuthGuard], data: {authGuardPipe:  redirectUnauthorizedToLogin}},
];

12. Opsional: aturan keamanan

Firestore dan Cloud Storage menggunakan aturan keamanan (masing-masing firestore.rules dan security.rules) untuk menerapkan keamanan dan memvalidasi data.

Saat ini, data Firestore dan Storage memiliki akses terbuka untuk operasi baca dan tulis, tetapi Anda tidak ingin orang mengubah postingan orang lain. Anda dapat menggunakan aturan keamanan untuk membatasi akses ke koleksi dan dokumen.

Aturan Firestore

Untuk hanya mengizinkan pengguna terautentikasi melihat postingan perjalanan, buka file firestore.rules dan tambahkan:

rules_version  =  '2';
service  cloud.firestore  {
	match  /databases/{database}/travels  {
		allow  read:  if  request.auth.uid  !=  null;
		allow  write:
		if  request.auth.uid  ==  request.resource.data.userId;
	}
}

Aturan keamanan juga dapat digunakan untuk memvalidasi data:

rules_version  =  '2';
service  cloud.firestore  {
	match  /databases/{database}/posts  {
		allow  read:  if  request.auth.uid  !=  null;
		allow  write:
		if  request.auth.uid  ==  request.resource.data.userId;
		&&  "author"  in  request.resource.data
		&&  "text"  in  request.resource.data
		&&  "timestamp"  in  request.resource.data;
	}
}

Aturan penyimpanan

Demikian pula, kita dapat menggunakan aturan keamanan untuk menerapkan akses ke database penyimpanan di storage.rules. Perhatikan bahwa kita juga dapat menggunakan fungsi untuk pemeriksaan yang lebih kompleks:

rules_version  =  '2';

function  isImageBelowMaxSize(maxSizeMB)  {
	return  request.resource.size  <  maxSizeMB  *  1024  *  1024
		&&  request.resource.contentType.matches('image/.*');
}

 service  firebase.storage  {
	match  /b/{bucket}/o  {
		match  /{userId}/{postId}/{filename}  {
			allow  write:  if  request.auth  !=  null
			&&  request.auth.uid  ==  userId  &&  isImageBelowMaxSize(5);
			allow  read;
		}
	}
}