Firebase Angular Web Çerçeveleri Codelab

1. Oluşturacağınız içerikler

Bu codelab'de, Angular kitaplığımızdaki son yeniliklerle (AngularFire) gerçek zamanlı ortak çalışmaya dayalı bir haritayla seyahat odaklı bir blog oluşturacaksınız. Son web uygulaması, seyahat ettiğiniz her konuma resim yükleyebileceğiniz bir seyahat blogundan oluşacak.

Web uygulamasını geliştirmek için AngularFire, yerel testler için Emulator Suite, kullanıcı verilerini izlemek için Authentication, verileri ve medyayı saklamak için Firestore ve Storage, Cloud Functions tarafından desteklenen son olarak da uygulamayı dağıtmak için Firebase Hosting kullanılacak.

Neler öğreneceksiniz?

  • Emulator Suite ile Firebase ürünleriyle yerel olarak geliştirme
  • Web uygulamanızı AngularFire ile geliştirme
  • Verilerinizi Firestore'da saklama
  • Medyayı Storage'da saklama
  • Uygulamanızı Firebase Hosting'e dağıtma
  • Veritabanlarınız ve API'lerinizle etkileşimde bulunmak için Cloud Functions'ı kullanma

Gerekenler

  • Node.js 10 sürümü veya üzeri
  • Firebase Projenizin oluşturulması ve yönetilmesi için bir Google Hesabı
  • Firebase CLI 11.14.2 veya sonraki bir sürüm
  • Tercih ettiğiniz bir tarayıcı (ör. Chrome)
  • Angular ve JavaScript ile ilgili temel bilgiler

2. Örnek kodu alın

Komut satırından codelab'in GitHub deposunu klonlayın:

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

Alternatif olarak, git yüklü değilse depoyu bir ZIP dosyası olarak indirebilirsiniz.

GitHub deposu, birden çok platform için örnek projeler içerir.

Bu codelab yalnızca web çerçevesi deposunu kullanır:

  • 📁 webframework: Bu codelab sırasında temel alacağınız başlangıç kodu.

Bağımlıları yükleme

Klonlama işleminden sonra, web uygulamasını derlemeden önce kök ve functions klasörüne bağımlılıkları yükleyin.

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

Firebase CLI'yi yükleyin

Bir terminalde şu komutu kullanarak Firebase CLI'ı yükleyin:

npm install -g firebase-tools

Aşağıdakileri kullanarak Firebase CLI sürümünüzün 11.14.2'den büyük olup olmadığını tekrar kontrol edin:

firebase  --version

Sürümünüz 11.14.2'den eskiyse lütfen aşağıdakileri kullanarak güncelleyin:

npm update firebase-tools

3. Firebase projesi oluşturma ve ayarlama

Firebase projesi oluşturma

  1. Firebase'de oturum açın.
  2. Firebase konsolunda Proje Ekle'yi tıklayın ve ardından Firebase projenizi <projeniz> olarak adlandırın. Firebase projenizin proje kimliğini unutmayın.
  3. Proje Oluştur'u tıklayın.

Önemli: Firebase projeniz <projeniz> olarak adlandırılır ancak Firebase, projenize otomatik olarak <projeniz>-1234 biçiminde benzersiz bir proje kimliği atar. Bu benzersiz tanımlayıcı, projenizin gerçekte nasıl tanımlandığını (KSA dahil) belirtirken <projeniz> görünen bir addır.

Derleeceğimiz uygulama, web uygulamaları için kullanılabilen Firebase ürünlerini kullanır:

  • Kullanıcılarınızın uygulamanızda kolayca oturum açmasına izin vermek için Firebase Authentication.
  • Yapılandırılmış verileri buluta kaydetmek ve veriler değiştiğinde anında bildirim almak için Cloud Firestore.
  • Dosyaları buluta kaydetmek için Cloud Storage for Firebase.
  • Öğelerinizi barındırmak ve yayınlamak için Firebase Hosting.
  • Dahili ve harici API'lerle etkileşime giren işlevler.

Bu ürünlerden bazılarının özel yapılandırmalar olması veya Firebase konsolu üzerinden etkinleştirilmesi gerekir.

Projeye bir Firebase web uygulaması ekleyin

  1. Yeni bir Firebase web uygulaması oluşturmak için web simgesini tıklayın.
  2. Sonraki adımda bir yapılandırma nesnesi görürsünüz. Bu nesnenin içeriğini environments/environment.ts dosyasına kopyalayın.

Firebase Authentication için Google ile Oturum Açma'yı etkinleştirin

Kullanıcıların web uygulamasında Google hesaplarıyla oturum açmasına izin vermek için Google oturum açma yöntemini kullanacağız.

Google ile oturum açmayı etkinleştirmek için:

  1. Firebase konsolunda sol panelden Derleme bölümünü bulun.
  2. Kimlik doğrulama'yı, ardından Oturum açma yöntemi sekmesini tıklayın (veya doğrudan bu sayfaya gitmek için burayı tıklayın).
  3. Google oturum açma sağlayıcısını etkinleştirin, ardından Kaydet'i tıklayın.
  4. Uygulamanızın herkese açık adını <projenizin-adı> olarak ayarlayın ve açılır menüden bir Proje desteği e-posta adresi seçin.

Cloud Firestore'u etkinleştirme

  1. Firebase konsolunun Derleme bölümünde Firestore Veritabanı'nı tıklayın.
  2. Cloud Firestore bölmesinde Create database'i (Veritabanı oluştur) tıklayın.
  3. Cloud Firestore verilerinizin saklanacağı konumu ayarlayın. Bunu varsayılan değer olarak bırakabilir veya size yakın bir bölge seçebilirsiniz.

Cloud Storage'ı etkinleştirme

Web uygulaması resimleri depolamak, yüklemek ve paylaşmak için Cloud Storage for Firebase'i kullanır.

  1. Firebase konsolunun Derleme bölümünde Depolama'yı tıklayın.
  2. Başlayın düğmesi görünmüyorsa Cloud Storage zaten hazır demektir.

ve aşağıdaki adımları uygulamanız gerekmez.

  1. Başlayın'ı tıklayın.
  2. Firebase projenizin güvenlik kurallarıyla ilgili sorumluluk reddi beyanını okuyup Sonraki'yi tıklayın.
  3. Cloud Storage konumu, Cloud Firestore veritabanınız için seçtiğiniz bölge kullanılarak önceden seçilmiştir. Kurulumu tamamlamak için Bitti'yi tıklayın.

Varsayılan güvenlik kuralları kullanıldığında, kimliği doğrulanmış her kullanıcı Cloud Storage'a her şeyi yazabilir. Bu codelab'in ilerleyen bölümlerinde depolama alanımızı daha güvenli hâle getireceğiz.

4. Firebase projenize bağlanın

Firebase komut satırı arayüzü (KSA), web uygulamanızı yerel olarak sunmak ve Firebase projenize dağıtmak için Firebase Hosting'i kullanmanıza olanak tanır.

Komut satırınızın, uygulamanızın yerel webframework dizinine eriştiğinden emin olun.

Web uygulaması kodunu Firebase projenize bağlayın. İlk olarak komut satırında Firebase CLI'ye giriş yapın:

firebase login

Ardından, proje takma adı oluşturmak için aşağıdaki komutu çalıştırın. $YOUR_PROJECT_ID kısmını Firebase projenizin kimliğiyle değiştirin.

firebase  use  $YOUR_PROJECT_ID

AngularFire ekle

AngularFire'ı uygulamaya eklemek için şu komutu çalıştırın:

ng add @angular/fire

Ardından, komut satırı talimatlarını uygulayın ve Firebase projenizde bulunan özellikleri seçin.

Firebase'i başlatma

Firebase projesini başlatmak için şu komutu çalıştırın:

firebase init

Ardından, komut satırı istemlerini izleyerek Firebase projenizde kullanılan özellikleri ve emülatörleri seçin.

Emülatörleri başlatma

webframework dizininden emülatörleri başlatmak için aşağıdaki komutu çalıştırın:

firebase  emulators:start

Sonunda şuna benzer bir sonuçla karşılaşırsınız:

$  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.

✔All emulators ready! mesajını gördüğünüzde emülatörler kullanıma hazırdır.

Seyahat uygulamanızın (henüz!) çalışmayan kullanıcı arayüzünü görürsünüz:

Haydi oluşturmaya başlayalım.

5. Web uygulamasını emülatörlere bağlama

Emülatör günlüklerindeki tabloya göre, Cloud Firestore emülatörü 8080 numaralı bağlantı noktasında, Kimlik Doğrulama emülatörü ise 9099 numaralı bağlantı noktasını dinliyor.

EmulatorUI'yi aç

Web tarayıcınızda http://127.0.0.1:4000/ adresine gidin. Emulator Suite kullanıcı arayüzünü görürsünüz.

Uygulamayı emülatörleri kullanacak şekilde yönlendirin

src/app/app.module.ts uygulamasında aşağıdaki kodu AppModule hesabının içe aktarma listesine ekleyin:

@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;
		}),
		...
	]

Uygulama artık yerel emülatörleri kullanacak şekilde yapılandırıldı. Bu sayede test ve geliştirme işlemleri yerel olarak gerçekleştirilebilir.

6. Kimlik Doğrulama Ekleme

Uygulama için emülatörler ayarlandığına göre her kullanıcının mesaj göndermeden önce oturum açmasını sağlamak için Kimlik Doğrulama özellikleri ekleyebiliriz.

Bunun için, signin işlevlerini doğrudan AngularFire'dan içe aktarabilir ve kullanıcınızın yetkilendirme durumunu authState işleviyle izleyebiliriz. Giriş sayfası işlevlerini, sayfanın yükleme sırasında kullanıcı kimlik doğrulaması durumunu kontrol edecek şekilde değiştirin.

AngularFire Kimlik Doğrulaması Yerleştirme

src/app/pages/login-page/login-page.component.ts ürününde, Auth dosyasını @angular/fire/auth kaynağından içe aktarın ve LoginPageComponent etiketine ekleyin. Google gibi kimlik doğrulama sağlayıcıları ve signin, signout gibi işlevler de aynı paketten doğrudan içe aktarılabilir ve uygulamada kullanılabilir.

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

Giriş sayfası artık çalışıyor! Giriş yapmayı deneyin ve Kimlik Doğrulama Emülatörü'ndeki sonuçlara göz atın.

7. Firestore'u yapılandırma

Bu adımda, Firestore'da depolanan seyahat blogu yayınlarını yayınlama ve güncelleme işlevi ekleyeceksiniz.

Authentication'a benzer şekilde Firestore işlevleri AngularFire'dan önceden paket halinde gelir. Her doküman bir koleksiyona aittir ve her dokümanda iç içe yerleştirilmiş koleksiyonlar da olabilir. Seyahat blogu yayını oluşturmak ve güncellemek için Firestore'daki belgenin path bölümünü bilmek gerekir.

TravelService'i Uygulama

Birçok farklı sayfanın web uygulamasındaki Firestore dokümanlarını okuması ve güncellemesi gerektiğinden, aynı AngularFire işlevlerini her sayfaya tekrar tekrar eklemekten kaçınmak için işlevleri src/app/services/travel.service.ts üzerinde uygulayabiliriz.

Önceki adıma benzer şekilde Auth ve hizmetimize Firestore öğesini ekleyerek başlayın. Mevcut kimlik doğrulama durumunu dinleyen gözlemlenebilir bir user$ nesnesi tanımlamak da yararlıdır.

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

Seyahat yayını ekleme

Seyahat yayınları, Firestore'da depolanan dokümanlar olarak bulunur ve dokümanların koleksiyonlarda bulunması gerektiğinden, tüm seyahat yayınlarını içeren koleksiyon travels olarak adlandırılır. Dolayısıyla, herhangi bir seyahat yayınının yolu travels/ şeklinde olur.

AngularFire'daki addDoc işlevi kullanılarak koleksiyona nesne eklenebilir:

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;

	})
}

Verileri güncelleme ve silme

Herhangi bir seyahat yayınının yardımıyla, Firestore'da depolanan belgenin yolu çıkarılabilir. Bu yol daha sonra AngularFire'ın updateFoc ve deleteDoc işlevleri kullanılarak okunabilir, güncellenebilir veya silinebilir:

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

Verileri gözlemlenebilir olarak okuma

Yol üzerindeki seyahat yayınları ve duraklar, oluşturma işleminden sonra değiştirilebilir. Bu nedenle, doküman nesnelerini gözlemlenebilir olarak almak ve yapılan değişikliklere abone olmak daha faydalı olur. Bu işlev, @angular/fire/firestore tarafından sağlanan docData ve collectionData işlevleri tarafından sunulmaktadır.

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[]>
}

Seyahat yayınına durak ekleme

Seyahat yayını çalışmalarının ayarlandığına göre artık mola verme zamanı geldi. Bu duraklar, aşağıdaki gibi bir seyahat yayını alt koleksiyonunda yer alacak: travels//stops/

Bu, seyahat gönderisi oluşturmakla neredeyse aynıdır. Bu nedenle, bunu kendi başınıza uygulamaya çalışın veya aşağıdaki uygulamaya göz atın:

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

Güzel! Firestore işlevleri Travel hizmetinde uygulanmıştır, böylece bunları iş başında görebilirsiniz.

Uygulamada Firestore işlevlerini kullanma

İşlevlerini kullanmak için src/app/pages/my-travels/my-travels.component.ts öğesine gidin ve TravelService öğesini ekleyin.

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

TravelService, tüm seyahatleri içeren bir Gözlemlenebilir dizisi elde etmek için oluşturucuda çağrılır.

Geçerli kullanıcının yalnızca seyahatinin gerekli olduğu durumlarda query işlevini kullanın.

Güvenliği sağlayan diğer yöntemler arasında güvenlik kuralları uygulamak veya aşağıdaki isteğe bağlı adımlarda açıklandığı gibi Firestore ile Cloud Functions'ı kullanmak yer alır

Ardından TravelService içinde uygulanan işlevleri çağırmanız yeterlidir.

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

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

Seyahatlerim sayfası artık çalışır durumda olmalıdır. Yeni bir seyahat yayını oluşturduğunuzda Firestore emülatörünüzde neler olduğuna bakın.

Daha sonra /src/app/pages/edit-travels/edit-travels.component.ts komutundaki güncelleme işlevleri için bu işlemi tekrarlayın :

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. Depolama Alanını Yapılandırma

Artık resimleri ve diğer medya türlerini depolamak için Depolama'yı uygularsınız.

Cloud Firestore, JSON nesneleri gibi yapılandırılmış verileri depolamak için en iyi seçenektir. Cloud Storage, dosyaları veya blob'ları depolamak için tasarlanmıştır. Bu uygulamada, kullanıcıların seyahat resimlerini paylaşmalarına izin vermek için kullanacaksınız.

Benzer şekilde Firestore'da da dosyaların Storage ile depolanması ve güncellenmesi her dosya için benzersiz bir tanımlayıcı gerektirir.

TraveService içindeki işlevleri uygulayalım:

Dosya yükleme

src/app/services/travel.service.ts adresine gidin ve AngularFire'dan Depolama Alanı ekleyin:

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

Ve yükleme işlevini uygulayın:

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

Dokümanlara Firestore'dan ve Cloud Storage'dan erişmek arasındaki temel fark, her ikisi de klasör yapılandırılmış yollarını izlemesine rağmen, temel URL ve yol kombinasyonunun getDownloadURL aracılığıyla elde edilmesidir. Bu kombinasyonun daha sonra bir dosyasında depolanıp kullanılabilmesidir.

İşlevi uygulamada kullanma

src/app/components/edit-stop/edit-stop.component.ts hizmetine gidin ve aşağıdakileri kullanarak yükleme işlevini çağırın:

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

Resim yüklendiğinde medya dosyasının kendisi depolama alanına yüklenir ve URL, Firestore'daki belgede uygun şekilde saklanır.

9. Uygulamanın dağıtılması

Artık uygulamayı dağıtmaya hazırız!

src/environments/environment.ts kaynağından src/environments/environment.prod.ts hedefine firebase yapılandırmasını kopyalayıp şu komutu çalıştırın:

firebase deploy

Aşağıdakine benzer bir tablo görürsünüz:

✔ 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. Tebrikler!

Uygulamanız tamamlanmış ve Firebase Hosting'e dağıtılmıştır. Artık tüm verilere ve analizlere Firebase Konsolunuzdan erişebilirsiniz.

AngularFire, Functions ve güvenlik kurallarıyla ilgili diğer özellikler için aşağıdaki isteğe bağlı adımlara ve diğer Firebase Codelabs'e göz atmayı unutmayın!

11. İsteğe bağlı: AngularFire kimlik doğrulama korumaları

AngularFire, Firebase Authentication'ın yanı sıra rotalarda kimlik doğrulama tabanlı korumalar da sunar. Böylece yeterli erişimi olmayan kullanıcılar yönlendirilebilir. Bu şekilde uygulamanın, korunan verilere erişen kullanıcılardan korunmasına yardımcı olursunuz.

src/app/app-routing.module.ts uygulamasında içe aktar

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

Ardından, kullanıcıların belirli sayfalarda ne zaman ve nereye yönlendirileceğine ilişkin işlevleri tanımlayabilirsiniz:

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

Daha sonra bunları rotalarınıza eklemeniz yeterlidir:

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. İsteğe bağlı: güvenlik kuralları

Güvenliği sağlamak ve verileri doğrulamak için hem Firestore hem de Cloud Storage güvenlik kuralları (sırasıyla firestore.rules ve security.rules) kullanır.

Şu anda Firestore ve Storage verileri okuma ve yazma için açık erişime sahiptir ancak kullanıcıların başkalarını değiştirmekle uğraşmasını istemezsiniz yayın! Koleksiyonlarınıza ve dokümanlarınıza erişimi kısıtlamak için güvenlik kurallarını kullanabilirsiniz.

Firestore kuralları

Yalnızca kimliği doğrulanmış kullanıcıların seyahat yayınlarını görüntülemesine izin vermek için firestore.rules dosyasına gidin ve şunları ekleyin:

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

Verileri doğrulamak için güvenlik kuralları da kullanılabilir:

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

Depolama kuralları

Benzer şekilde, storage.rules ürününde depolama veritabanlarına erişimi zorunlu kılmak için güvenlik kurallarından yararlanabiliriz. Daha karmaşık kontroller için işlevleri de kullanabileceğimizi unutmayın:

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