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

১. তুমি কী তৈরি করবে

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

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

তুমি কি শিখবে

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

তোমার যা লাগবে

  • Node.js ভার্সন ১০ বা তার বেশি
  • আপনার Firebase প্রকল্প তৈরি এবং পরিচালনার জন্য একটি Google অ্যাকাউন্ট
  • ফায়ারবেস সিএলআই সংস্করণ ১১.১৪.২ বা তার পরবর্তী সংস্করণ
  • আপনার পছন্দের একটি ব্রাউজার, যেমন Chrome
  • অ্যাঙ্গুলার এবং জাভাস্ক্রিপ্টের প্রাথমিক ধারণা

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

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

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

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

গিথুব রিপোজিটরিতে একাধিক প্ল্যাটফর্মের জন্য নমুনা প্রকল্প রয়েছে।

এই কোডল্যাবটি শুধুমাত্র ওয়েবফ্রেমওয়ার্ক রিপোজিটরি ব্যবহার করে:

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

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

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

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

ফায়ারবেস সিএলআই ইনস্টল করুন

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

npm install -g firebase-tools

আপনার Firebase CLI সংস্করণটি 11.14.2 এর চেয়ে বড় কিনা তা দুবার পরীক্ষা করুন:

firebase  --version

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

npm update firebase-tools

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

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

  1. আপনার গুগল অ্যাকাউন্ট ব্যবহার করে ফায়ারবেস কনসোলে সাইন ইন করুন।
  2. একটি নতুন প্রকল্প তৈরি করতে বোতামটি ক্লিক করুন, এবং তারপর একটি প্রকল্পের নাম লিখুন (উদাহরণস্বরূপ, FriendlyChat )।
  3. চালিয়ে যান ক্লিক করুন।
  4. যদি অনুরোধ করা হয়, তাহলে Firebase শর্তাবলী পর্যালোচনা করুন এবং গ্রহণ করুন, এবং তারপর Continue এ ক্লিক করুন।
  5. (ঐচ্ছিক) Firebase কনসোলে ("Gemini in Firebase" নামে পরিচিত) AI সহায়তা সক্ষম করুন।
  6. এই কোডল্যাবের জন্য, আপনার গুগল অ্যানালিটিক্সের প্রয়োজন নেই , তাই গুগল অ্যানালিটিক্স বিকল্পটি টগল করে বন্ধ করে দিন
  7. Create project এ ক্লিক করুন, আপনার province করার জন্য অপেক্ষা করুন, এবং তারপর Continue এ ক্লিক করুন।

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

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

Firebase পণ্য সেট আপ করুন

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

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

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

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

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

গুগল সাইন-ইন সক্ষম করতে:

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

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

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

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

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

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

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

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

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

৪. আপনার ফায়ারবেস প্রকল্পের সাথে সংযোগ করুন

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

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

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

firebase login

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

firebase  use  $YOUR_PROJECT_ID

অ্যাঙ্গুলারফায়ার যোগ করুন

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

ng add @angular/fire

তারপর, কমান্ড লাইন নির্দেশাবলী অনুসরণ করুন, এবং আপনার 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! বার্তাটি দেখতে পেলে, এমুলেটরগুলি ব্যবহারের জন্য প্রস্তুত।

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

এবার নির্মাণ শুরু করা যাক!

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

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

এমুলেটরইউআই খুলুন।

আপনার ওয়েব ব্রাউজারে, 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;
		}),
		...
	]

অ্যাপটি এখন স্থানীয় এমুলেটর ব্যবহারের জন্য কনফিগার করা হয়েছে, যার ফলে স্থানীয়ভাবে পরীক্ষা এবং উন্নয়ন করা সম্ভব হবে।

৬. প্রমাণীকরণ যোগ করা

এখন অ্যাপটির জন্য এমুলেটর সেট আপ করা হয়েছে, আমরা প্রমাণীকরণ বৈশিষ্ট্য যোগ করতে পারি যাতে প্রতিটি ব্যবহারকারী বার্তা পোস্ট করার আগে সাইন ইন করে থাকেন।

এটি করার জন্য, আমরা AngularFire থেকে সরাসরি signin ফাংশন আমদানি করতে পারি এবং authState ফাংশনের সাহায্যে আপনার ব্যবহারকারীর auth অবস্থা ট্র্যাক করতে পারি। লগইন পৃষ্ঠার ফাংশনগুলি এমনভাবে পরিবর্তন করুন যাতে পৃষ্ঠাটি লোড হওয়ার সময় ব্যবহারকারীর auth অবস্থা পরীক্ষা করে।

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

এখন লগইন পৃষ্ঠাটি কার্যকর! লগ ইন করার চেষ্টা করুন, এবং প্রমাণীকরণ এমুলেটরে ফলাফলগুলি দেখুন।

৭. ফায়ারস্টোর কনফিগার করা

এই ধাপে, আপনি ফায়ারস্টোরে সংরক্ষিত ভ্রমণ ব্লগ পোস্ট পোস্ট এবং আপডেট করার কার্যকারিতা যোগ করবেন।

প্রমাণীকরণের মতোই, Firestore ফাংশনগুলি AngularFire থেকে প্রি-প্যাকেজ করা হয়। প্রতিটি ডকুমেন্ট একটি সংগ্রহের অন্তর্গত, এবং প্রতিটি ডকুমেন্টে নেস্টেড সংগ্রহও থাকতে পারে। একটি ভ্রমণ ব্লগ পোস্ট তৈরি এবং আপডেট করার জন্য Firestore-এ ডকুমেন্টের path জানা প্রয়োজন।

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

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

আমাদের পরিষেবাতে পূর্ববর্তী ধাপের মতো 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);

একটি ভ্রমণ পোস্ট যোগ করা হচ্ছে

ভ্রমণ পোস্টগুলি ফায়ারস্টোরে সংরক্ষিত নথি হিসাবে বিদ্যমান থাকবে এবং যেহেতু নথিগুলি সংগ্রহের মধ্যেই থাকতে হবে, তাই সমস্ত ভ্রমণ পোস্ট ধারণকারী সংগ্রহের নামকরণ করা হবে 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;

	})
}

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

যেকোনো ভ্রমণ পোস্টের ইউআইডি দিয়ে, ফায়ারস্টোরে সংরক্ষিত ডকুমেন্টের পাথ বের করা যায়, যা পরে 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})
}

দারুন! ট্র্যাভেল সার্ভিসে ফায়ারস্টোর ফাংশনগুলি বাস্তবায়িত হয়েছে, তাই এখন আপনি সেগুলিকে কার্যকরভাবে দেখতে পাচ্ছেন।

অ্যাপে ফায়ারস্টোর ফাংশন ব্যবহার করা

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

এখন মাই ট্রাভেলস পৃষ্ঠাটি কার্যকরী হওয়া উচিত! নতুন ভ্রমণ পোস্ট তৈরি করলে আপনার ফায়ারস্টোর এমুলেটরে কী ঘটে তা দেখুন।

তারপর, /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[]>

}

৮. স্টোরেজ কনফিগার করা

ছবি এবং অন্যান্য ধরণের মিডিয়া সংরক্ষণের জন্য আপনি এখন স্টোরেজ প্রয়োগ করবেন।

ক্লাউড ফায়ারস্টোর 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টি ফায়ারস্টোরের নথিতে সংরক্ষণ করা হবে।

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

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

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

১০. অভিনন্দন!

এখন আপনার অ্যাপ্লিকেশনটি সম্পূর্ণ এবং Firebase Hosting-এ স্থাপন করা উচিত! সমস্ত ডেটা এবং বিশ্লেষণ এখন আপনার Firebase কনসোলে অ্যাক্সেসযোগ্য হবে।

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

১২. ঐচ্ছিক: নিরাপত্তা নিয়ম

ফায়ারস্টোর এবং ক্লাউড স্টোরেজ উভয়ই সুরক্ষা প্রয়োগ এবং ডেটা যাচাই করার জন্য সুরক্ষা নিয়ম (যথাক্রমে 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;
		}
	}
}