ফায়ারবেস কৌণিক ওয়েব ফ্রেমওয়ার্ক কোডল্যাব

1. আপনি কি তৈরি করবেন

এই কোডল্যাবে, আপনি আমাদের কৌণিক লাইব্রেরি থেকে সর্বশেষের সাথে একটি রিয়েল-টাইম সহযোগী মানচিত্র সহ একটি ভ্রমণ ব্লগ তৈরি করবেন: AngularFire । চূড়ান্ত ওয়েব অ্যাপে একটি ভ্রমণ ব্লগ থাকবে যেখানে আপনি ভ্রমণ করেছেন এমন প্রতিটি স্থানে ছবি আপলোড করতে পারবেন।

AngularFire ওয়েব অ্যাপ তৈরি করতে ব্যবহার করা হবে, স্থানীয় পরীক্ষার জন্য এমুলেটর স্যুট, ব্যবহারকারীর ডেটা ট্র্যাক রাখার জন্য প্রমাণীকরণ, ফায়ারস্টোর এবং স্টোরেজ ডেটা এবং মিডিয়া বজায় রাখার জন্য, ক্লাউড ফাংশন দ্বারা চালিত, এবং অবশেষে, অ্যাপটি স্থাপন করার জন্য ফায়ারবেস হোস্টিং।

আপনি কি শিখবেন

  • এমুলেটর স্যুটের সাথে স্থানীয়ভাবে ফায়ারবেস পণ্যগুলির সাথে কীভাবে বিকাশ করবেন
  • অ্যাঙ্গুলারফায়ার দিয়ে কীভাবে আপনার ওয়েব অ্যাপ উন্নত করবেন
  • ফায়ারস্টোরে আপনার ডেটা কীভাবে বজায় রাখবেন
  • স্টোরেজে মিডিয়া কীভাবে বজায় রাখা যায়
  • ফায়ারবেস হোস্টিং-এ কীভাবে আপনার অ্যাপ স্থাপন করবেন
  • আপনার ডাটাবেস এবং API এর সাথে ইন্টারঅ্যাক্ট করতে ক্লাউড ফাংশনগুলি কীভাবে ব্যবহার করবেন

আপনি কি প্রয়োজন হবে

  • Node.js সংস্করণ 10 বা উচ্চতর
  • আপনার ফায়ারবেস প্রকল্প তৈরি এবং পরিচালনার জন্য একটি Google অ্যাকাউন্ট
  • Firebase CLI সংস্করণ 11.14.2 বা তার পরে
  • আপনার পছন্দের একটি ব্রাউজার, যেমন Chrome
  • কৌণিক এবং জাভাস্ক্রিপ্টের প্রাথমিক ধারণা

2. নমুনা কোড পান

কমান্ড লাইন থেকে কোডল্যাবের গিটহাব সংগ্রহস্থল ক্লোন করুন:

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

বিকল্পভাবে, যদি আপনার গিট ইনস্টল না থাকে, আপনি একটি ZIP ফাইল হিসাবে সংগ্রহস্থল ডাউনলোড করতে পারেন।

Github সংগ্রহস্থলে একাধিক প্ল্যাটফর্মের জন্য নমুনা প্রকল্প রয়েছে।

এই কোডল্যাব শুধুমাত্র ওয়েবফ্রেমওয়ার্ক সংগ্রহস্থল ব্যবহার করে:

  • 📁 ওয়েবফ্রেমওয়ার্ক : এই কোডল্যাবের সময় আপনি যে প্রারম্ভিক কোডটি তৈরি করবেন।

নির্ভরতা ইনস্টল করুন

ক্লোনিংয়ের পরে, ওয়েব অ্যাপ তৈরি করার আগে রুট এবং functions ফোল্ডারে নির্ভরতা ইনস্টল করুন।

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

Firebase CLI ইনস্টল করুন

একটি টার্মিনালে এই কমান্ডটি ব্যবহার করে Firebase CLI ইনস্টল করুন:

npm install -g firebase-tools

আপনার Firebase CLI ভার্সন 11.14.2 এর থেকে বড় তা ব্যবহার করে দুবার চেক করুন:

firebase  --version

যদি আপনার সংস্করণ 11.14.2 এর চেয়ে কম হয়, তাহলে অনুগ্রহ করে এটি ব্যবহার করে আপডেট করুন:

npm update firebase-tools

3. একটি ফায়ারবেস প্রকল্প তৈরি এবং সেট আপ করুন৷

একটি ফায়ারবেস প্রকল্প তৈরি করুন

  1. Firebase এ সাইন ইন করুন।
  2. ফায়ারবেস কনসোলে, প্রজেক্ট যোগ করুন ক্লিক করুন এবং তারপর আপনার ফায়ারবেস প্রকল্পের নাম দিন <your-project> । আপনার ফায়ারবেস প্রকল্পের জন্য প্রজেক্ট আইডি মনে রাখবেন।
  3. প্রকল্প তৈরি করুন ক্লিক করুন।

গুরুত্বপূর্ণ : আপনার ফায়ারবেস প্রকল্পের নাম দেওয়া হবে <your-project> , কিন্তু Firebase স্বয়ংক্রিয়ভাবে এটিকে <your-project>-1234 ফর্মে একটি অনন্য প্রকল্প আইডি বরাদ্দ করবে। এই অনন্য শনাক্তকারী হল আপনার প্রকল্পটি আসলে কীভাবে চিহ্নিত করা হয় (CLI সহ), যেখানে <your-project> হল একটি প্রদর্শন নাম।

আমরা যে অ্যাপ্লিকেশনটি তৈরি করতে যাচ্ছি সেটি ফায়ারবেস পণ্য ব্যবহার করে যা ওয়েব অ্যাপের জন্য উপলব্ধ:

  • Firebase প্রমাণীকরণ সহজেই আপনার ব্যবহারকারীদের আপনার অ্যাপে সাইন ইন করার অনুমতি দেয়।
  • ক্লাউড ফায়ারস্টোর ক্লাউডে স্ট্রাকচার্ড ডেটা সংরক্ষণ করতে এবং ডেটা পরিবর্তন হলে তাৎক্ষণিক বিজ্ঞপ্তি পেতে।
  • ক্লাউডে ফাইল সংরক্ষণ করার জন্য ফায়ারবেসের জন্য ক্লাউড স্টোরেজ
  • Firebase হোস্টিং হোস্ট এবং আপনার সম্পদ পরিবেশন.
  • অভ্যন্তরীণ এবং বহিরাগত API-এর সাথে ইন্টারঅ্যাক্ট করার ফাংশন

এই পণ্যগুলির মধ্যে কিছু বিশেষ কনফিগারেশন প্রয়োজন বা Firebase কনসোল ব্যবহার করে সক্ষম করা প্রয়োজন।

প্রকল্পে একটি Firebase ওয়েব অ্যাপ যোগ করুন

  1. একটি নতুন Firebase ওয়েব অ্যাপ তৈরি করতে ওয়েব আইকনে ক্লিক করুন।
  2. পরবর্তী ধাপে, আপনি একটি কনফিগারেশন অবজেক্ট দেখতে পাবেন। environments/environment.ts ফাইলে এই বস্তুর বিষয়বস্তু অনুলিপি করুন।

Firebase প্রমাণীকরণের জন্য Google সাইন-ইন সক্ষম করুন

ব্যবহারকারীদের তাদের Google অ্যাকাউন্ট দিয়ে ওয়েব অ্যাপে সাইন ইন করার অনুমতি দিতে, আমরা Google সাইন-ইন পদ্ধতি ব্যবহার করব।

Google সাইন-ইন সক্ষম করতে:

  1. Firebase কনসোলে, বাম প্যানেলে বিল্ড বিভাগটি সনাক্ত করুন।
  2. প্রমাণীকরণ ক্লিক করুন, তারপর সাইন-ইন পদ্ধতি ট্যাবে ক্লিক করুন (বা সরাসরি সেখানে যেতে এখানে ক্লিক করুন )।
  3. Google সাইন-ইন প্রদানকারী সক্ষম করুন, তারপর সংরক্ষণ করুন ক্লিক করুন৷
  4. আপনার অ্যাপের সর্বজনীন-মুখী নাম <your-project-name> এ সেট করুন এবং ড্রপডাউন মেনু থেকে একটি প্রকল্প সমর্থন ইমেল চয়ন করুন।

ক্লাউড ফায়ারস্টোর সক্ষম করুন

  1. Firebase কনসোলের বিল্ড বিভাগে, Firestore Database-এ ক্লিক করুন।
  2. ক্লাউড ফায়ারস্টোর ফলকে ডেটাবেস তৈরি করুন ক্লিক করুন।
  3. আপনার ক্লাউড ফায়ারস্টোর ডেটা যেখানে সংরক্ষিত আছে সেটি সেট করুন। আপনি এটিকে ডিফল্ট হিসাবে ছেড়ে যেতে পারেন বা আপনার কাছাকাছি একটি অঞ্চল বেছে নিতে পারেন৷

ক্লাউড স্টোরেজ সক্ষম করুন

ওয়েব অ্যাপটি ছবি সংরক্ষণ, আপলোড এবং শেয়ার করতে Firebase-এর জন্য ক্লাউড স্টোরেজ ব্যবহার করে।

  1. Firebase কনসোলের বিল্ড বিভাগে, স্টোরেজ ক্লিক করুন।
  2. যদি কোনও শুরু করার বোতাম না থাকে তবে এর অর্থ হল ক্লাউড স্টোরেজ ইতিমধ্যেই রয়েছে৷

সক্রিয়, এবং আপনাকে নীচের পদক্ষেপগুলি অনুসরণ করতে হবে না৷

  1. শুরু করুন ক্লিক করুন।
  2. আপনার ফায়ারবেস প্রকল্পের নিরাপত্তা নিয়ম সম্পর্কে দাবিত্যাগ পড়ুন, তারপর পরবর্তী ক্লিক করুন।
  3. ক্লাউড স্টোরেজ অবস্থানটি আপনার ক্লাউড ফায়ারস্টোর ডাটাবেসের জন্য আপনি যে অঞ্চলটি বেছে নিয়েছেন তার সাথে পূর্বনির্বাচিত। সেটআপ সম্পূর্ণ করতে সম্পন্ন ক্লিক করুন।

ডিফল্ট নিরাপত্তা নিয়মের সাথে, যেকোনো প্রমাণীকৃত ব্যবহারকারী ক্লাউড স্টোরেজে যেকোনো কিছু লিখতে পারে। আমরা পরবর্তীতে এই কোডল্যাবে আমাদের স্টোরেজকে আরও সুরক্ষিত করে তুলব।

4. আপনার Firebase প্রকল্পের সাথে সংযোগ করুন৷

Firebase কমান্ড-লাইন ইন্টারফেস (CLI) আপনাকে স্থানীয়ভাবে আপনার ওয়েব অ্যাপ পরিবেশন করতে, সেইসাথে আপনার Firebase প্রকল্পে আপনার ওয়েব অ্যাপ স্থাপন করতে Firebase হোস্টিং ব্যবহার করতে দেয়।

নিশ্চিত করুন যে আপনার কমান্ড লাইন আপনার অ্যাপের স্থানীয় webframework ডিরেক্টরি অ্যাক্সেস করছে।

আপনার Firebase প্রকল্পে ওয়েব অ্যাপ কোডটি সংযুক্ত করুন। প্রথমে, কমান্ড লাইনে Firebase CLI-তে লগ ইন করুন:

firebase login

পরবর্তীতে একটি প্রকল্প উপনাম তৈরি করতে নিম্নলিখিত কমান্ডটি চালান। আপনার Firebase প্রকল্পের ID দিয়ে $YOUR_PROJECT_ID প্রতিস্থাপন করুন।

firebase  use  $YOUR_PROJECT_ID

AngularFire যোগ করুন

অ্যাপে AngularFire যোগ করতে, কমান্ডটি চালান:

ng add @angular/fire

তারপর, কমান্ড লাইন নির্দেশাবলী অনুসরণ করুন এবং আপনার ফায়ারবেস প্রকল্পে বিদ্যমান বৈশিষ্ট্যগুলি নির্বাচন করুন।

ফায়ারবেস শুরু করুন

ফায়ারবেস প্রকল্প শুরু করতে, চালান:

firebase init

তারপর, কমান্ড লাইন প্রম্পট অনুসরণ করে, আপনার ফায়ারবেস প্রকল্পে ব্যবহৃত বৈশিষ্ট্য এবং এমুলেটরগুলি নির্বাচন করুন।

এমুলেটরগুলি শুরু করুন

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! বার্তা, এমুলেটরগুলি ব্যবহারের জন্য প্রস্তুত।

আপনার ভ্রমণ অ্যাপের UI দেখতে হবে, যা (এখনও!) কাজ করছে না:

এখন এর নির্মাণ করা যাক!

5. এমুলেটরগুলির সাথে ওয়েব অ্যাপটি সংযুক্ত করুন৷

এমুলেটর লগের টেবিলের উপর ভিত্তি করে, ক্লাউড ফায়ারস্টোর এমুলেটর পোর্ট 8080 এ শুনছে এবং প্রমাণীকরণ এমুলেটর পোর্ট 9099 এ শুনছে।

EmulatorUI খুলুন

আপনার ওয়েব ব্রাউজারে, http://127.0.0.1:4000/ এ নেভিগেট করুন। আপনার এমুলেটর স্যুট UI দেখতে হবে।

এমুলেটর ব্যবহার করতে অ্যাপটিকে রুট করুন

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 Auth ইনজেকশন

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-এ নথির path জানা প্রয়োজন৷

ট্রাভেল সার্ভিস বাস্তবায়ন

যেহেতু ওয়েব অ্যাপে ফায়ারস্টোর ডকুমেন্টগুলি পড়তে এবং আপডেট করার জন্য অনেকগুলি বিভিন্ন পৃষ্ঠার প্রয়োজন হবে, তাই আমরা src/app/services/travel.service.ts এ ফাংশনগুলি প্রয়োগ করতে পারি, প্রতি পৃষ্ঠায় একই অ্যাঙ্গুলারফায়ার ফাংশন বারবার ইনজেকশন করা থেকে বিরত থাকতে।

পূর্ববর্তী ধাপের মতো, সেইসাথে আমাদের পরিষেবাতে Firestore অনুরূপ Auth ইনজেকশন দিয়ে শুরু করুন। একটি পর্যবেক্ষণযোগ্য 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;

	})
}

ডেটা আপডেট করা এবং মুছে ফেলা হচ্ছে

যেকোন ভ্রমণ পোস্টের uid দেওয়া হলে, কেউ 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/ travels/ /stops/

এটি একটি ট্রাভেল পোস্ট তৈরির প্রায় অনুরূপ, তাই এটি নিজে থেকে বাস্তবায়ন করার জন্য নিজেকে চ্যালেঞ্জ করুন, অথবা নীচের বাস্তবায়নটি দেখুন:

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

চমৎকার! 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-এর সাথে ক্লাউড ফাংশন ব্যবহার করা যেমন নিচের ঐচ্ছিক ধাপে অন্বেষণ করা হয়েছে

তারপরে, 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. স্টোরেজ কনফিগার করা

আপনি এখন ছবি এবং অন্যান্য ধরনের মিডিয়া সঞ্চয় করার জন্য সঞ্চয়স্থান বাস্তবায়ন করবেন।

JSON অবজেক্টের মতো স্ট্রাকচার্ড ডেটা সঞ্চয় করতে ক্লাউড ফায়ারস্টোর সবচেয়ে ভালো ব্যবহার করা হয়। ক্লাউড স্টোরেজ ফাইল বা ব্লব সংরক্ষণ করার জন্য ডিজাইন করা হয়েছে। এই অ্যাপে, আপনি ব্যবহারকারীদের তাদের ভ্রমণের ছবি শেয়ার করার অনুমতি দিতে এটি ব্যবহার করবেন।

একইভাবে ফায়ারস্টোরের সাথে, স্টোরেজের সাথে ফাইলগুলি সংরক্ষণ এবং আপডেট করার জন্য প্রতিটি ফাইলের জন্য একটি অনন্য শনাক্তকারী প্রয়োজন।

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

ফায়ারস্টোর থেকে নথি এবং ক্লাউড স্টোরেজ থেকে ফাইলগুলি অ্যাক্সেস করার মধ্যে প্রাথমিক পার্থক্য হল, যদিও তারা উভয়ই ফোল্ডার স্ট্রাকচার্ড পাথ অনুসরণ করে, বেস ইউআরএল এবং পাথ সংমিশ্রণ 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);
}

যখন ছবিটি আপলোড করা হয়, তখন মিডিয়া ফাইলটি নিজেই স্টোরেজে আপলোড হবে এবং সেই অনুযায়ী url Firestore-এ নথিতে সংরক্ষণ করা হবে।

9. অ্যাপ্লিকেশন স্থাপন করা

এখন আমরা অ্যাপ্লিকেশন স্থাপন করার জন্য প্রস্তুত!

src/environments/environment.ts থেকে src/environments/environment.prod.tsfirebase কনফিগারেশন কপি করুন এবং চালান:

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, ফাংশন, নিরাপত্তা বিধি সম্পর্কিত আরও বৈশিষ্ট্যের জন্য, নীচের ঐচ্ছিক পদক্ষেপগুলি, সেইসাথে অন্যান্য ফায়ারবেস কোডল্যাবগুলি পরীক্ষা করতে ভুলবেন না!

11. ঐচ্ছিক: AngularFire auth guards

ফায়ারবেস প্রমাণীকরণের পাশাপাশি, AngularFire রুটে প্রমাণীকরণ ভিত্তিক গার্ডও অফার করে, যাতে অপর্যাপ্ত অ্যাক্সেস সহ ব্যবহারকারীদের পুনঃনির্দেশিত করা যায়। এটি ব্যবহারকারীদের সুরক্ষিত ডেটা অ্যাক্সেস করা থেকে অ্যাপটিকে রক্ষা করতে সহায়তা করে।

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.rules এবং security.rules ) নিরাপত্তা প্রয়োগ করতে এবং ডেটা যাচাই করতে।

এই মুহুর্তে, ফায়ারস্টোর এবং স্টোরেজ ডেটা পড়ার এবং লেখার জন্য উন্মুক্ত অ্যাক্সেস রয়েছে, কিন্তু আপনি চান না যে লোকেরা অন্যের পোস্টগুলি পরিবর্তন করুক! আপনি আপনার সংগ্রহ এবং নথি অ্যাক্সেস সীমাবদ্ধ করতে নিরাপত্তা নিয়ম ব্যবহার করতে পারেন.

ফায়ারস্টোরের নিয়ম

শুধুমাত্র প্রমাণীকৃত ব্যবহারকারীদের ভ্রমণ পোস্ট দেখার অনুমতি দিতে, 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;
		}
	}
}