Firebase Angular Web Frameworks Codelab

1. आपको क्या बनाना होगा

इस कोडलैब में, आपको यात्रा से जुड़ा एक ब्लॉग बनाना होगा. इसमें, हमारी Angular लाइब्रेरी के सबसे नए वर्शन के साथ मिलकर रीयल-टाइम मैप होगा: AngularFire. अंतिम वेब ऐप्लिकेशन में एक यात्रा ब्लॉग होगा, जिसमें आप हर उस स्थान के लिए चित्र अपलोड कर सकते हैं जहां आप जा चुके हैं.

AngularFire का इस्तेमाल वेब ऐप्लिकेशन, लोकल टेस्टिंग के लिए एम्युलेटर सुइट, उपयोगकर्ता के डेटा पर नज़र रखने के लिए पुष्टि करने, डेटा और मीडिया को बनाए रखने के लिए, Firestore और स्टोरेज के लिए किया जाएगा. इसके अलावा, ऐप्लिकेशन को डिप्लॉय करने के लिए Firebase होस्टिंग का इस्तेमाल किया जाएगा.

आपको यह जानकारी मिलेगी

  • Emulator Suite की मदद से, Firebase प्रॉडक्ट को स्थानीय तौर पर डेवलप करने का तरीका
  • AngularFire की मदद से, अपने वेब ऐप्लिकेशन को बेहतर कैसे बनाएं
  • अपने डेटा को Firestore में सेव रखने का तरीका
  • मीडिया को स्टोरेज में सेव रखने का तरीका
  • अपने ऐप्लिकेशन को Firebase होस्टिंग पर डिप्लॉय करने का तरीका
  • अपने डेटाबेस और एपीआई के साथ इंटरैक्ट करने के लिए, Cloud Functions इस्तेमाल करने का तरीका

आपको इन चीज़ों की ज़रूरत होगी

  • Node.js का 10 या उसके बाद वाला वर्शन
  • Firebase प्रोजेक्ट बनाने और मैनेज करने के लिए Google खाता
  • Firebase सीएलआई का 11.14.2 या उसके बाद का वर्शन
  • आपकी पसंद का ब्राउज़र, जैसे कि Chrome
  • ऐंग्युलर और JavaScript की बुनियादी समझ

2. सैंपल कोड पाएं

कमांड लाइन से, कोडलैब की GitHub रिपॉज़िटरी का क्लोन बनाएं:

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

इसके अलावा, अगर आपने GitHub फ़ाइल इंस्टॉल नहीं की है, तो डेटा स्टोर करने की जगह को ZIP फ़ाइल के रूप में डाउनलोड करें.

GitHub रिपॉज़िटरी में कई प्लैटफ़ॉर्म के लिए सैंपल प्रोजेक्ट शामिल हैं.

यह कोडलैब सिर्फ़ वेबफ़्रेमवर्क डेटा स्टोर करने की जगह का इस्तेमाल करता है:

  • 📁 वेबफ़्रेमवर्क: शुरुआती कोड, जिसे आप इस कोडलैब के दौरान बनाएंगे.

डिपेंडेंसी इंस्टॉल करें

क्लोन करने के बाद, वेब ऐप्लिकेशन बनाने से पहले रूट और functions फ़ोल्डर में डिपेंडेंसी इंस्टॉल करें.

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

Firebase सीएलआई इंस्टॉल करें

टर्मिनल में इस निर्देश का इस्तेमाल करके, Firebase सीएलआई इंस्टॉल करें:

npm install -g firebase-tools

इसका इस्तेमाल करके दोबारा जांच करें कि आपका Firebase सीएलआई वर्शन 11.14.2 से बाद का है या नहीं:

firebase  --version

अगर आपके ऐप्लिकेशन का वर्शन 11.14.2 से पहले का है, तो कृपया इनका इस्तेमाल करके अपडेट करें:

npm update firebase-tools

3. Firebase प्रोजेक्ट बनाना और उसे सेट अप करना

Firebase प्रोजेक्ट बनाना

  1. Firebase में साइन इन करें.
  2. Firebase कंसोल में, प्रोजेक्ट जोड़ें पर क्लिक करें और फिर अपने Firebase प्रोजेक्ट को <your-project> का नाम दें. अपने Firebase प्रोजेक्ट का प्रोजेक्ट आईडी याद रखें.
  3. प्रोजेक्ट बनाएं पर क्लिक करें.

ज़रूरी जानकारी: आपके Firebase प्रोजेक्ट को <your-project> नाम दिया जाएगा, लेकिन Firebase अपने-आप इसे <your-project>-1234 के रूप में एक यूनीक प्रोजेक्ट आईडी असाइन करेगा. इस यूनीक आइडेंटिफ़ायर से असल में आपके प्रोजेक्ट की पहचान होती है (इसमें सीएलआई भी शामिल है), जबकि <your-project> की पहचान सिर्फ़ एक डिसप्ले नेम के तौर पर की जाती है.

हम जो ऐप्लिकेशन बनाने जा रहे हैं उसमें वे Firebase प्रॉडक्ट इस्तेमाल किए जाते हैं जो वेब ऐप्लिकेशन के लिए उपलब्ध हैं:

  • Firebase से पुष्टि करने की सुविधा का इस्तेमाल करके, उपयोगकर्ता आपके ऐप्लिकेशन में आसानी से साइन इन कर सकते हैं.
  • स्ट्रक्चर्ड डेटा को क्लाउड पर सेव करने और डेटा में बदलाव होने पर तुरंत सूचना पाने के लिए, Cloud Firestore.
  • क्लाउड में फ़ाइलों को सेव करने के लिए, Firebase के लिए Cloud Storage का इस्तेमाल करें.
  • आपके ऐसेट होस्ट करने और उन्हें उपलब्ध कराने के लिए, Firebase होस्टिंग.
  • इंटरनल और एक्सटर्नल एपीआई के साथ इंटरैक्ट करने के लिए फ़ंक्शन.

इनमें से कुछ प्रॉडक्ट के लिए खास कॉन्फ़िगरेशन की ज़रूरत होती है या उन्हें Firebase कंसोल का इस्तेमाल करके चालू करना पड़ता है.

प्रोजेक्ट में Firebase वेब ऐप्लिकेशन जोड़ना

  1. Firebase का नया वेब ऐप्लिकेशन बनाने के लिए, वेब आइकॉन पर क्लिक करें.
  2. अगले चरण में, आपको एक कॉन्फ़िगरेशन ऑब्जेक्ट दिखेगा. इस ऑब्जेक्ट के कॉन्टेंट को environments/environment.ts फ़ाइल में कॉपी करें.

Firebase से पुष्टि करने के लिए Google साइन-इन की सुविधा चालू करें

उपयोगकर्ताओं को उनके Google खाते से वेब ऐप्लिकेशन में साइन इन करने की अनुमति देने के लिए, हम Google से साइन इन करने के तरीके का इस्तेमाल करेंगे.

Google में साइन-इन करने की सुविधा चालू करने के लिए:

  1. Firebase कंसोल में, बाएं पैनल में बिल्ड सेक्शन पर जाएं.
  2. पुष्टि करने पर क्लिक करें. इसके बाद, साइन इन करने का तरीका टैब पर क्लिक करें या सीधे वहां जाने के लिए यहां क्लिक करें.
  3. Google की, साइन इन करने की सेवा देने वाली कंपनी को चालू करें. इसके बाद, सेव करें पर क्लिक करें.
  4. अपने ऐप्लिकेशन का सार्वजनिक नाम <your-project-name> पर सेट करें और ड्रॉपडाउन मेन्यू से प्रोजेक्ट सहायता ईमेल चुनें.

Cloud Firestore को चालू करें

  1. Firebase कंसोल के बिल्ड सेक्शन में, डेटाबेस को फिर से स्टोर करें पर क्लिक करें.
  2. Cloud Firestore पैनल में डेटाबेस बनाएं पर क्लिक करें.
  3. वह जगह सेट करें जहां आपका Cloud Firestore डेटा स्टोर किया गया है. इसे डिफ़ॉल्ट तौर पर छोड़ा जा सकता है या अपने आस-पास का इलाका चुना जा सकता है.

Cloud Storage चालू करना

वेब ऐप्लिकेशन में फ़ोटो सेव, अपलोड, और शेयर करने के लिए, 'Firebase के लिए Cloud Storage' का इस्तेमाल किया जाता है.

  1. Firebase कंसोल के बिल्ड सेक्शन में, स्टोरेज पर क्लिक करें.
  2. अगर शुरू करें बटन नहीं दिखता है, तो इसका मतलब है कि Cloud Storage पहले से ही मौजूद है

सक्षम किया गया है, और आपको नीचे दिए गए चरणों का पालन करने की आवश्यकता नहीं है.

  1. शुरू करें पर क्लिक करें.
  2. अपने Firebase प्रोजेक्ट के सुरक्षा नियमों से जुड़ा डिसक्लेमर पढ़ें. इसके बाद, आगे बढ़ें पर क्लिक करें.
  3. Cloud Storage की जगह वही इलाका पहले से चुना गया है, जिसे आपने अपने Cloud Firestore डेटाबेस के लिए चुना है. सेटअप पूरा करने के लिए, हो गया पर क्लिक करें.

सुरक्षा के डिफ़ॉल्ट नियमों का इस्तेमाल करके, पुष्टि किया गया कोई भी उपयोगकर्ता Cloud Storage में कुछ भी लिख सकता है. बाद में, कोडलैब के इस वर्शन में स्टोरेज को और ज़्यादा सुरक्षित बनाया जाएगा.

4. अपने Firebase प्रोजेक्ट से कनेक्ट करना

Firebase कमांड-लाइन इंटरफ़ेस (सीएलआई) की मदद से, Firebase होस्टिंग का इस्तेमाल करके अपने वेब ऐप्लिकेशन को स्थानीय तौर पर उपलब्ध कराया जा सकता है. साथ ही, वेब ऐप्लिकेशन को Firebase प्रोजेक्ट में डिप्लॉय किया जा सकता है.

पक्का करें कि कमांड लाइन, आपके ऐप्लिकेशन की लोकल webframework डायरेक्ट्री को ऐक्सेस कर रही हो.

वेब ऐप्लिकेशन कोड को अपने Firebase प्रोजेक्ट से कनेक्ट करें. सबसे पहले, कमांड लाइन में Firebase सीएलआई में लॉग इन करें:

firebase login

इसके बाद, प्रोजेक्ट का उपनाम बनाने के लिए, यहां दिया गया कमांड चलाएं. $YOUR_PROJECT_ID को अपने Firebase प्रोजेक्ट के आईडी से बदलें.

firebase  use  $YOUR_PROJECT_ID

AngularFire जोड़ें

AngularFire को ऐप्लिकेशन में जोड़ने के लिए, यह निर्देश चलाएं:

ng add @angular/fire

फिर, कमांड लाइन निर्देशों का पालन करें और अपने Firebase प्रोजेक्ट में मौजूद सुविधाओं को चुनें.

Firebase शुरू करें

Firebase प्रोजेक्ट शुरू करने के लिए, इसे चलाएं:

firebase init

इसके बाद, कमांड लाइन प्रॉम्प्ट का इस्तेमाल करके, वे सुविधाएं और एम्युलेटर चुनें जिन्हें आपके Firebase प्रोजेक्ट में इस्तेमाल किया गया था.

एम्युलेटर शुरू करें

एम्युलेटर शुरू करने के लिए, webframework डायरेक्ट्री से नीचे दिया गया निर्देश चलाएं:

firebase  emulators:start

आखिर में, आपको कुछ ऐसा दिखेगा:

$  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! मैसेज दिखे, तो एम्युलेटर का इस्तेमाल किया जा सकता है.

आपको अपने यात्रा से जुड़े ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई) दिखेगा, जो (अब तक!) काम नहीं कर रहा है:

चलिए, अब इमारत बनाने की शुरुआत करते हैं!

5. वेब ऐप्लिकेशन को एम्युलेटर से कनेक्ट करें

एम्युलेटर लॉग में मौजूद टेबल के मुताबिक, Cloud Firestore एम्युलेटर, पोर्ट 8080 पर सुन रहा है और पुष्टि करने वाला एम्युलेटर, पोर्ट 9099 पर सुन रहा है.

EmulatorUI खोलें

अपने वेब ब्राउज़र में, http://127.0.0.1:4000/ पर जाएं. आपको Emulator Suite का यूज़र इंटरफ़ेस (यूआई) दिखेगा.

एम्युलेटर का इस्तेमाल करने के लिए ऐप्लिकेशन को रूट करें

src/app/app.module.ts में, 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;
		}),
		...
	]

ऐप्लिकेशन को अब लोकल एम्युलेटर का इस्तेमाल करने के लिए कॉन्फ़िगर कर दिया गया है. इससे स्थानीय तौर पर जांच और डेवलपमेंट की जा सकेगी.

6. पुष्टि करने की सुविधा जोड़ना

अब ऐप्लिकेशन के लिए एम्युलेटर सेट अप कर दिए गए हैं. इसलिए, हम पुष्टि करने की सुविधाएं जोड़ सकते हैं. इससे यह पक्का किया जा सकेगा कि मैसेज पोस्ट करने से पहले हर उपयोगकर्ता ने साइन इन किया हो.

ऐसा करने के लिए, हम सीधे AngularFire से signin फ़ंक्शन इंपोर्ट कर सकते हैं. साथ ही, authState फ़ंक्शन की मदद से, आपके उपयोगकर्ता के पुष्टि करने की स्थिति को ट्रैक कर सकते हैं. लॉगिन पेज के फ़ंक्शन में बदलाव करें, ताकि पेज लोड होने पर उपयोगकर्ता की पुष्टि की स्थिति की जांच करे.

AngularFire पुष्टि इंजेक्ट करना

src/app/pages/login-page/login-page.component.ts में, @angular/fire/auth से Auth इंपोर्ट करें और उसे LoginPageComponent में इंजेक्ट करें. Google जैसे पुष्टि करने वाले डिवाइसों और signin, signout जैसे फ़ंक्शन को भी सीधे उसी पैकेज से इंपोर्ट किया जा सकता है और ऐप्लिकेशन में इस्तेमाल किया जा सकता है.

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

अब लॉगिन पेज काम करने लगा! लॉग इन करने की कोशिश करें और ऑथेंटिकेशन एम्युलेटर में नतीजे देखें.

7. Firestore को कॉन्फ़िगर करना

इस चरण में, आपको Firestore में सेव की गई यात्रा से जुड़ी ब्लॉग पोस्ट को पोस्ट और अपडेट करने की सुविधा जोड़नी होगी.

ऑथेंटिकेशन की तरह ही, Firestore फ़ंक्शन AngularFire से पहले से पैकेज किए जाते हैं. हर दस्तावेज़ किसी कलेक्शन से जुड़ा होता है और हर दस्तावेज़ में नेस्ट किए गए कलेक्शन भी हो सकते हैं. ट्रैवल ब्लॉग पोस्ट बनाने और उसे अपडेट करने के लिए, Firestore में दस्तावेज़ के path की जानकारी होना ज़रूरी है.

TravelService को लागू करना

वेब ऐप्लिकेशन में कई अलग-अलग पेजों को Firestore दस्तावेज़ों को पढ़ने और अपडेट करने की ज़रूरत होती है. इसलिए, हम हर पेज में एक ही AngularFire फ़ंक्शन को बार-बार इंजेक्ट करने से बचने के लिए, src/app/services/travel.service.ts में फ़ंक्शन लागू कर सकते हैं.

पिछले चरण की तरह ही Auth को इंजेक्ट करना शुरू करें. साथ ही, हमारी सेवा में Firestore को इंजेक्ट करें. पुष्टि करने की मौजूदा स्थिति को सुनने वाले, मॉनिटर किए जा सकने वाले user$ ऑब्जेक्ट को तय करना भी मददगार होता है.

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

यात्रा से जुड़ी पोस्ट जोड़ना

यात्रा से जुड़ी पोस्ट, Firestore में सेव किए गए दस्तावेज़ों के तौर पर मौजूद होंगी. साथ ही, कलेक्शन में दस्तावेज़ भी होने चाहिए. इसलिए, उस संग्रह का नाम travels होगा जिसमें यात्रा से जुड़ी सभी पोस्ट शामिल हैं. इस प्रकार, किसी भी यात्रा पोस्ट का पथ travels/ होगा

AngularFire के addDoc फ़ंक्शन का इस्तेमाल करके, किसी ऑब्जेक्ट को संग्रह में शामिल किया जा सकता है:

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;

	})
}

डेटा अपडेट करना और मिटाना

किसी भी यात्रा पोस्ट के यूआईडी को देखते हुए, कोई व्यक्ति Firestore में सेव किए गए दस्तावेज़ के पाथ का पता लगा सकता है. इसके बाद, उसे AngularFire के updateFoc और deleteDoc फ़ंक्शन का इस्तेमाल करके, पढ़ा जा सकता है, अपडेट किया जा सकता है या मिटाया जा सकता है:

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

डेटा को मॉनिटर किए जा सकने वाले फ़ॉर्मैट के तौर पर पढ़ना

ऐसा इसलिए, क्योंकि यात्रा से जुड़ी पोस्ट और रास्ते के दौरान आने वाले स्टॉप में बदलाव किए जा सकते हैं. इसलिए, दस्तावेज़ से जुड़ी चीज़ों को मॉनिटर करने के लिए पाना ज़्यादा मददगार होगा. इससे उन्हें किसी भी तरह के बदलाव की सदस्यता लेने में मदद मिलेगी. यह फ़ंक्शन, @angular/fire/firestore के docData और collectionData फ़ंक्शन से ऑफ़र किया जाता है.

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

यात्रा की पोस्ट में स्टॉप जोड़ना

अब यात्रा से जुड़ी पोस्ट की कार्रवाइयां सेट अप कर दी गई हैं, इसलिए अब स्टॉप को चुनने का समय आ गया है, जो यात्रा से जुड़ी पोस्ट के सब-कलेक्शन के तहत मौजूद होंगे, जैसे: travels//stops/

यह काम किसी ट्रैवल पोस्ट जैसा ही होता है. इसलिए, खुद से इसे लागू करने का चैलेंज दें या इसे लागू करने के लिए नीचे देखें:

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

बहुत बढ़िया! यात्रा से जुड़ी सेवा में, Firestore फ़ंक्शन लागू किए गए हैं. इसलिए, अब आप उन्हें काम करते हुए देख सकते हैं.

ऐप्लिकेशन में Firestore फ़ंक्शन इस्तेमाल करना

src/app/pages/my-travels/my-travels.component.ts पर जाएं और TravelService को इंजेक्ट करें, ताकि इसके फ़ंक्शन इस्तेमाल किए जा सकें.

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

सभी यात्राओं का मॉनिटर किया जा सकने वाला कलेक्शन पाने के लिए, TravelService को कंस्ट्रक्टर में कॉल किया जाता है.

ऐसे मामले में जहां सिर्फ़ मौजूदा उपयोगकर्ता की यात्रा की ज़रूरत हो, query फ़ंक्शन का इस्तेमाल करें.

सुरक्षा पक्का करने के दूसरे तरीकों में, सुरक्षा के नियमों को लागू करना या Firestore के साथ Cloud Functions का इस्तेमाल करना शामिल है, जैसा कि नीचे वैकल्पिक चरणों में बताया गया है

इसके बाद, बस TravelService में लागू किए गए फ़ंक्शन को कॉल करें.

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

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

अब 'मेरी यात्रा' पेज काम करने लगेगा! देखें कि यात्रा के बारे में नई पोस्ट बनाने पर, आपके Firestore एम्युलेटर में क्या होता है.

इसके बाद, /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. स्टोरेज कॉन्फ़िगर करना

अब इमेज और दूसरी तरह के मीडिया को स्टोर करने के लिए, स्टोरेज को लागू किया जाएगा.

Cloud Firestore का इस्तेमाल, JSON ऑब्जेक्ट जैसे स्ट्रक्चर्ड डेटा को स्टोर करने के लिए किया जाता है. Cloud Storage को फ़ाइलों या ब्लॉब को स्टोर करने के लिए डिज़ाइन किया गया है. इस ऐप्लिकेशन में, उपयोगकर्ताओं को अपनी यात्रा की तस्वीरें शेयर करने की अनुमति देने के लिए इसका इस्तेमाल किया जा सकता है.

Firestore की तरह ही, स्टोरेज में फ़ाइलों को सेव और अपडेट करने के लिए, हर फ़ाइल के लिए एक यूनीक आइडेंटिफ़ायर की ज़रूरत होती है.

आइए, TraveService में फ़ंक्शन लागू करते हैं:

फ़ाइल अपलोड करना

src/app/services/travel.service.ts पर जाएं और AngularFire से स्टोरेज इंजेक्ट करें:

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

और अपलोड फ़ंक्शन लागू करें:

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

Firestore से दस्तावेज़ों और Cloud Storage की फ़ाइलों को ऐक्सेस करने के बीच मुख्य अंतर यह है कि ये दोनों, फ़ोल्डर के स्ट्रक्चर्ड पाथ के हिसाब से होते हैं, लेकिन बेस यूआरएल और पाथ कॉम्बिनेशन, getDownloadURL के ज़रिए लिया जाता है. इसके बाद, इसे फ़ाइल में सेव और इस्तेमाल किया जा सकता है.

ऐप्लिकेशन में फ़ंक्शन का इस्तेमाल करना

src/app/components/edit-stop/edit-stop.component.ts पर जाएं और इनका इस्तेमाल करके अपलोड फ़ंक्शन को कॉल करें:

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

इमेज अपलोड होने के बाद, मीडिया फ़ाइल अपने-आप स्टोरेज में अपलोड हो जाएगी और यूआरएल को Firestore में उसी हिसाब से सेव किया जाएगा.

9. ऐप्लिकेशन को डिप्लॉय करना

अब हम ऐप्लिकेशन को डिप्लॉय करने के लिए तैयार हैं!

firebase कॉन्फ़िगरेशन को src/environments/environment.ts से src/environments/environment.prod.ts पर कॉपी करें और चलाएं:

firebase deploy

आपको कुछ ऐसा दिखेगा:

 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. बधाई हो!

अब आपका ऐप्लिकेशन पूरा हो गया होगा और उसे Firebase होस्टिंग में डिप्लॉय किया जाना चाहिए! अब सभी डेटा और आंकड़ों को आपके Firebase कंसोल में ऐक्सेस किया जा सकेगा.

AngularFire, फ़ंक्शन, और सुरक्षा नियमों के बारे में ज़्यादा सुविधाओं के लिए, नीचे दिए गए वैकल्पिक चरणों के साथ-साथ अन्य Firebase कोड लैब देखना न भूलें!

11. ज़रूरी नहीं: AngularFire के पुष्टि करने वाले गार्ड

AngularFire में, Firebase से पुष्टि करने की सुविधा के साथ-साथ रूट पर सुरक्षा से जुड़े गार्ड भी होते हैं. इनकी मदद से, ज़रूरी ऐक्सेस वाले उपयोगकर्ताओं को रीडायरेक्ट किया जा सकता है. इससे, ऐप्लिकेशन को सुरक्षित डेटा ऐक्सेस करने से रोकने में मदद मिलती है.

src/app/app-routing.module.ts में, इंपोर्ट करें

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

इसके बाद, फ़ंक्शन तय करके यह तय किया जा सकता है कि उपयोगकर्ताओं को चुनिंदा पेजों पर कब और कहां रीडायरेक्ट किया जाना चाहिए:

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

इसके बाद, उन्हें अपने रास्तों में जोड़ें:

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. ज़रूरी नहीं: सुरक्षा के नियम

सुरक्षा लागू करने और डेटा की पुष्टि करने के लिए, Firestore और Cloud Storage, दोनों सुरक्षा नियमों का इस्तेमाल करते हैं. जैसे- firestore.rules और security.rules.

इस समय, Firestore और स्टोरेज डेटा के पास पढ़ने और लिखने के लिए ओपन ऐक्सेस है, लेकिन आप नहीं चाहते कि लोग दूसरों को बदलें पोस्ट! सुरक्षा के नियमों का इस्तेमाल करके, अपने कलेक्शन और दस्तावेज़ों के ऐक्सेस पर पाबंदी लगाई जा सकती है.

Firestore के नियम

सिर्फ़ पुष्टि किए गए उपयोगकर्ताओं को यात्रा से जुड़ी पोस्ट देखने की अनुमति देने के लिए, firestore.rules फ़ाइल पर जाएं और यह जोड़ें:

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

सुरक्षा नियमों का इस्तेमाल डेटा की पुष्टि करने के लिए भी किया जा सकता है:

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

स्टोरेज के नियम

इसी तरह, हम storage.rules में स्टोरेज डेटाबेस का ऐक्सेस लागू करने के लिए, सुरक्षा के नियमों का इस्तेमाल कर सकते हैं. ध्यान दें कि हम ज़्यादा बारीकी से जांच करने के लिए भी फ़ंक्शन का इस्तेमाल कर सकते हैं:

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