ঝাঁকুনির জন্য ফায়ারবেস সম্পর্কে জানুন

1. আপনি শুরু করার আগে

এই codelab, আপনি বেসিক কিছু শিখবেন Firebase Android এবং iOS এর জন্য পাখির মোবাইল অ্যাপস তৈরি করুন।

পূর্বশর্ত

এই codelab অনুমান আপনি পাখির সাথে পরিচিত, এবং আপনি ইনস্টল করা আছে পাখির SDK এর , এবং একজন সম্পাদক

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

এই কোডল্যাবে আপনি Flutter ব্যবহার করে Android, iOS, ওয়েব এবং macOS-এ একটি ইভেন্ট RSVP এবং গেস্টবুক চ্যাট অ্যাপ তৈরি করবেন। আপনি Firebase প্রমাণীকরণের মাধ্যমে ব্যবহারকারীদের প্রমাণীকরণ করবেন এবং ক্লাউড ফায়ারস্টোর ব্যবহার করে ডেটা সিঙ্ক করবেন।

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

আপনি নিম্নলিখিত ডিভাইসগুলির যেকোনো একটি ব্যবহার করে এই কোডল্যাবটি চালাতে পারেন:

উপরের ছাড়াও, আপনার প্রয়োজন হবে:

  • আপনার পছন্দের একটি ব্রাউজার, যেমন Chrome।
  • একটি IDE বা যেমন আপনার পছন্দের টেক্সট এডিটর, অ্যান্ড্রয়েড স্টুডিও বা বনাম কোড ডার্ট এবং পাখির প্লাগিন এর মাধ্যমে কনফিগার।
  • সর্বশেষ stable সংস্করণ পাখির (অথবা beta আপনি কিনারায় বসবাস করেন)।
  • আপনার ফায়ারবেস প্রকল্প তৈরি এবং পরিচালনার জন্য একটি জিমেইল অ্যাকাউন্টের মতো একটি Google অ্যাকাউন্ট।
  • firebase কমান্ড লাইন টুল , আপনার Gmail অ্যাকাউন্টে লগ ইন।
  • কোডল্যাবের নমুনা কোড। কোডটি কিভাবে পেতে হয় তার পরবর্তী ধাপ দেখুন।

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

GitHub থেকে আমাদের প্রকল্পের প্রাথমিক সংস্করণ ডাউনলোড করে শুরু করা যাক।

ক্লোন GitHub সংগ্রহস্থলের কম্যান্ড লাইন থেকে:

git clone https://github.com/flutter/codelabs.git flutter-codelabs

অন্যথা, আপনি আছে যদি GitHub এর CLI টুল ইনস্টল হয়েছে:

gh repo clone flutter/codelabs flutter-codelabs

নমুনা কোড মধ্যে ক্লোন করা উচিত flutter-codelabs ডিরেক্টরি, যা codelabs একটি সংগ্রহ কোড ধারণ করে। এই codelab কোড রয়েছে flutter-codelabs/firebase-get-to-know-flutter

অধীনে ডিরেক্টরি গঠন flutter-codelabs/firebase-get-to-know-flutter যেখানে আপনি প্রতিটি নামে পদক্ষেপ শেষে হওয়া উচিত স্ন্যাপশট একটি সিরিজ। এটি ধাপ 2, তাই মিলে যাওয়া ফাইলগুলি সনাক্ত করা যতটা সহজ:

cd flutter-codelabs/firebase-get-to-know-flutter/step_02

আপনি যদি এড়িয়ে যেতে চান, বা একটি ধাপের পরে কিছু দেখতে কেমন হওয়া উচিত তা দেখতে চাইলে, আপনার আগ্রহের ধাপের নাম অনুসারে নির্দেশিকাটি দেখুন।

স্টার্টার অ্যাপ আমদানি করুন

ওপেন বা আমদানি flutter-codelabs/firebase-get-to-know-flutter/step_02 আপনার পছন্দের আইডিই মধ্যে ডিরেক্টরি। এই ডিরেক্টরিতে কোডল্যাবের প্রারম্ভিক কোড রয়েছে যা একটি এখনও কার্যকরী নয় ফ্লাটার মিটআপ অ্যাপ নিয়ে গঠিত।

কাজ করার জন্য ফাইলগুলি সনাক্ত করুন

এই অ্যাপের কোড একাধিক ডিরেক্টরিতে ছড়িয়ে আছে। কার্যকারিতার এই বিভাজনটি কার্যকারিতা অনুসারে কোড গ্রুপ করে কাজ করা সহজ করার জন্য ডিজাইন করা হয়েছে।

প্রকল্পে নিম্নলিখিত ফাইলগুলি সনাক্ত করুন:

  • lib/main.dart : এই ফাইলটি প্রধান এন্ট্রি পয়েন্ট এবং আবেদন উইজেট উপস্থিত রয়েছে।
  • lib/src/widgets.dart : এই ফাইলটি আবেদন স্টাইলিং সাহায্যের STANDARDIZE উইজেট থাবা ধারণ করে। এগুলি স্টার্টার অ্যাপের স্ক্রিন রচনা করতে ব্যবহৃত হয়।
  • lib/src/authentication.dart : এই ফাইলের একটি আংশিক বাস্তবায়ন রয়েছে FirebaseUI প্রমাণীকরণ উইজেট একটি সেট Firebase ইমেল ভিত্তিক প্রমাণীকরণের জন্য একটি লগইন ব্যবহারকারীর অভিজ্ঞতা তৈরি করার সুবিধা। প্রমাণীকরণ প্রবাহের জন্য এই উইজেটগুলি এখনও স্টার্টার অ্যাপে ব্যবহার করা হয়নি, তবে আপনি শীঘ্রই সেগুলিকে সংযুক্ত করবেন৷

বাকি অ্যাপ্লিকেশন তৈরি করার জন্য প্রয়োজন অনুযায়ী আপনি অতিরিক্ত ফাইল যোগ করবেন।

পর্যালোচনা lib/main.dart ফাইল

এই অ্যাপ্লিকেশানটি সুবিধা নেয় google_fonts পুরো অ্যাপ্লিকেশন সর্বত্র তে Roboto ডিফল্ট হরফ করতে এটি আমাদের সক্রিয় করতে প্যাকেজ। উদ্দেশ্যমূলক পাঠকদের জন্য একটি ব্যায়াম অন্বেষণ করা হয় fonts.google.com এবং আপনি অ্যাপ্লিকেশন বিভিন্ন স্থানে সেখানে আবিষ্কার ফন্ট ব্যবহার করুন।

আপনি এর থেকে সাহায্যকারী উইজেট ব্যবহার করা হয় lib/src/widgets.dart আকারে Header , Paragraph এবং IconAndDetail । এই উইজেট বর্ণিত পৃষ্ঠার লেআউট মধ্যে গোলমাল কমাতে HomePage সদৃশ কোড নির্মূল করে। এটি একটি সামঞ্জস্যপূর্ণ চেহারা এবং অনুভূতি সক্ষম করার অতিরিক্ত সুবিধা রয়েছে।

Android, iOS, ওয়েব এবং macOS-এ আপনার অ্যাপটি কেমন দেখায় তা এখানে:

অ্যাপের পূর্বরূপ

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

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

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

  1. সাইন ইন করুন Firebase
  2. Firebase কনসোলে, ক্লিক করুন প্রকল্প যোগ (বা একটি প্রকল্প তৈরি করুন), এবং আপনার Firebase প্রকল্পের Firebase-পাখির-Codelab নাম দিন।

4395e4e67c08043a.png

  1. প্রকল্প তৈরির বিকল্পগুলির মাধ্যমে ক্লিক করুন। অনুরোধ করা হলে Firebase শর্তাবলী স্বীকার করুন। Google Analytics সেট আপ করা এড়িয়ে যান, কারণ আপনি এই অ্যাপের জন্য Analytics ব্যবহার করবেন না।

b7138cde5f2c7b61.png

Firebase প্রকল্পগুলি সম্পর্কে আরও জানতে, Firebase প্রকল্প বুঝুন

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

  • Firebase প্রমাণীকরণ আপনার ব্যবহারকারীদের আপনার অ্যাপ্লিকেশানে সাইন ইন করতে অনুমতি দেয়।
  • ক্লাউড Firestore মেঘ কাঠামোবদ্ধ ডেটা সংরক্ষণ এবং ডেটা পরিবর্তন ঝটপট বিজ্ঞপ্তি পাবেন।
  • Firebase সিকিউরিটি রুলস আপনার ডাটাবেস সুরক্ষিত করতে।

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

সক্রিয় করুন ইমেল Firebase প্রমাণীকরণের জন্য সাইন-ইন

ব্যবহারকারীরা ওয়েব অ্যাপ্লিকেশন সাইন ইন করার অনুমতি দিতে, এই codelab জন্য পদ্ধতি সাইন-ইন ইমেইল / পাসওয়ার্ড ব্যবহার করব:

  1. Firebase কনসোলে, বাম প্যানেলে মেনু বিল্ড প্রসারিত।
  2. প্রমাণীকরণ ক্লিক করুন, এবং তারপর পান শুরু বোতাম, তারপর সাইন-ইন পদ্ধতি ট্যাব ক্লিক করুন (বা এখানে ক্লিক করুন সাইন-ইন পদ্ধতি ট্যাবে সরাসরি যেতে)।
  3. প্রদানকারীর সাইন-ইন তালিকায় ইমেইল / পাসওয়ার্ড ক্লিক করুন, সেট অবস্থান উপর স্যুইচটি সক্ষম করুন, এবং তারপর সংরক্ষণ ক্লিক করুন। 58e3e3e23c2f16a4.png

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

ওয়েব অ্যাপ্লিকেশন ব্যবহার ক্লাউড Firestore চ্যাট বার্তা সংরক্ষণ করুন এবং নতুন চ্যাট বার্তা প্রাপ্ত সদস্যতা।

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

  1. Firebase কনসোলের বিল্ড বিভাগে, ক্লাউড Firestore ক্লিক করুন।
  2. ডেটাবেস তৈরি করে ক্লিক করুন। 99e8429832d23fa3.png
  1. পরীক্ষা মোডে বিকল্প স্টার্ট নির্বাচন করুন। নিরাপত্তা নিয়ম সম্পর্কে দাবিত্যাগ পড়ুন. টেস্ট মোড নিশ্চিত করে যে আপনি বিকাশের সময় অবাধে ডাটাবেসে লিখতে পারেন। পরবর্তী ক্লিক করুন। 6be00e26c72ea032.png
  1. আপনার ডাটাবেসের জন্য অবস্থান নির্বাচন করুন (আপনি শুধু ডিফল্ট ব্যবহার করতে পারেন)। মনে রাখবেন এই অবস্থানটি পরে পরিবর্তন করা যাবে না। 278656eefcfb0216.png
  2. সক্ষম করুন এ ক্লিক করুন।

4. ফায়ারবেস কনফিগারেশন

Flutter এর সাথে Firebase ব্যবহার করার জন্য, FlutterFire লাইব্রেরিগুলিকে সঠিকভাবে ব্যবহার করার জন্য আপনাকে Flutter প্রোজেক্ট কনফিগার করার জন্য একটি প্রক্রিয়া অনুসরণ করতে হবে:

  • আপনার প্রকল্পে FlutterFire নির্ভরতা যোগ করুন
  • Firebase প্রকল্পে পছন্দসই প্ল্যাটফর্ম নিবন্ধন করুন৷
  • প্ল্যাটফর্ম-নির্দিষ্ট কনফিগারেশন ফাইলটি ডাউনলোড করুন এবং কোডে যোগ করুন।

আপনার পাখির অ্যাপের টপ লেভেল ডিরেক্টরির ইন, সাবডিরেক্টরি বলা হয় android , ios , macos এবং web । এই ডিরেক্টরিগুলি যথাক্রমে iOS এবং Android এর জন্য প্ল্যাটফর্ম-নির্দিষ্ট কনফিগারেশন ফাইল ধারণ করে।

নির্ভরতা কনফিগার করুন

আপনি এই অ্যাপে যে দুটি ফায়ারবেস পণ্য ব্যবহার করছেন তার জন্য আপনাকে FlutterFire লাইব্রেরি যোগ করতে হবে - Firebase Auth এবং Cloud Firestore। নির্ভরতা যোগ করতে নিম্নলিখিত তিনটি কমান্ড চালান।

$ flutter pub add firebase_core 
Resolving dependencies...
+ firebase_core 1.10.5
+ firebase_core_platform_interface 4.2.2
+ firebase_core_web 1.5.2
+ flutter_web_plugins 0.0.0 from sdk flutter
+ js 0.6.3
  test_api 0.4.3 (0.4.8 available)
Changed 5 dependencies!

firebase_core সাধারণ কোড সব Firebase পাখির প্লাগিন জন্য প্রয়োজন।

$ flutter pub add firebase_auth
Resolving dependencies...
+ firebase_auth 3.3.3
+ firebase_auth_platform_interface 6.1.8
+ firebase_auth_web 3.3.4
+ intl 0.17.0
  test_api 0.4.3 (0.4.8 available)
Changed 4 dependencies!

firebase_auth Firebase এর প্রমাণীকরণ সামর্থ্য সঙ্গে ইন্টিগ্রেশন সক্ষম করে।

$ flutter pub add cloud_firestore
Resolving dependencies...
+ cloud_firestore 3.1.4
+ cloud_firestore_platform_interface 5.4.9
+ cloud_firestore_web 2.6.4
  test_api 0.4.3 (0.4.8 available)
Changed 3 dependencies!

cloud_firestore ক্লাউড Firestore তথ্য সংগ্রহের এক্সেস দেয়।

$ flutter pub add provider
Resolving dependencies...
+ nested 1.0.0
+ provider 6.0.1
  test_api 0.4.3 (0.4.8 available)
Changed 2 dependencies!

আপনি প্রয়োজনীয় প্যাকেজ যোগ করার সময়, Firebase যথাযথভাবে ব্যবহার করার জন্য আপনাকে iOS, Android, macOS এবং ওয়েব রানার প্রকল্পগুলিও কনফিগার করতে হবে। এছাড়াও আপনি ব্যবহার করছেন provider প্যাকেজ যে প্রদর্শন যুক্তিবিজ্ঞান থেকে বিজনেস লজিক বিচ্ছেদ সক্ষম করবে।

ইনস্টল করার প্রক্রিয়া flutterfire

  1. FlutterFire CLI অন্তর্নিহিত Firebase CLI এর উপর নির্ভর করে। আপনি যদি ইতিমধ্যেই সম্পন্ন না করে থাকেন, ইনস্টল অথবা এর সর্বশেষ সংস্করণে আপডেট করুন Firebase CLI
  2. : এর পরে, নিম্নলিখিত কমান্ডের দ্বারা FlutterFire CLI ইনস্টল
    $ dart pub global activate flutterfire_cli
    

ইনস্টলেশন সমাপ্তির পরে, flutterfire কমান্ড বিশ্বব্যাপী উপলব্ধ হবে।

আপনার অ্যাপস কনফিগার করা হচ্ছে

CLI একটি নির্দিষ্ট প্ল্যাটফর্মের জন্য সমস্ত কনফিগারেশন তৈরি করতে আপনার Firebase প্রকল্প এবং নির্বাচিত প্রকল্প অ্যাপ্লিকেশন থেকে তথ্য বের করে।

আপনার অ্যাপ্লিকেশনের রুটে, কনফিগার কমান্ডটি চালান:

$ flutterfire configure

কনফিগারেশন কমান্ড আপনাকে বেশ কয়েকটি প্রক্রিয়ার মাধ্যমে গাইড করবে:

  1. একটি Firebase প্রকল্প নির্বাচন করা (.firebaserc ফাইলের উপর ভিত্তি করে বা Firebase কনসোল থেকে)।
  2. আপনি কোন প্ল্যাটফর্মের (যেমন Android, iOS, macOS এবং ওয়েব) কনফিগারেশন চান তা প্রম্পট করুন।
  3. নির্বাচিত প্ল্যাটফর্মগুলির জন্য কোন Firebase অ্যাপ্লিকেশনগুলির জন্য কনফিগারেশন বের করতে ব্যবহার করা উচিত তা সনাক্ত করুন৷ ডিফল্টরূপে, CLI আপনার বর্তমান প্রজেক্ট কনফিগারেশনের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে Firebase অ্যাপগুলির সাথে মিল করার চেষ্টা করবে।
  4. আপনার প্রকল্পে একটি firebase_options.dart ফাইল তৈরি করুন।

macOS কনফিগার করুন

macOS-এ ফ্লটার সম্পূর্ণরূপে স্যান্ডবক্সযুক্ত অ্যাপ্লিকেশন তৈরি করে। যেহেতু এই অ্যাপ্লিকেশনটি Firebase সার্ভারগুলির সাথে যোগাযোগের জন্য নেটওয়ার্ক ব্যবহার করে একীভূত হচ্ছে, তাই আপনাকে নেটওয়ার্ক ক্লায়েন্টের সুবিধাগুলির সাথে আপনার অ্যাপ্লিকেশনটি কনফিগার করতে হবে৷

macos/Runner/DebugProfile.entitlements

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
  <!-- Add the following two lines -->
	<key>com.apple.security.network.client</key>
	<true/>
</dict>
</plist>

macos/Runner/Release.entitlements

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.app-sandbox</key>
	<true/>
  <!-- Add the following two lines -->
	<key>com.apple.security.network.client</key>
	<true/>
</dict>
</plist>

দেখুন এনটাইটেলমেন্ট এবং অ্যাপ স্যান্ডবক্স আরো বিস্তারিত জন্য।

5. ব্যবহারকারী সাইন-ইন যোগ করুন (RSVP)

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

আপনি ধাপ 2 এ যে প্রকল্পটি পুনরুদ্ধার করেছেন তাতে উইজেটের একটি সেট অন্তর্ভুক্ত রয়েছে যা বেশিরভাগ প্রমাণীকরণ প্রবাহের জন্য ব্যবহারকারী ইন্টারফেস প্রয়োগ করে। আপনি অ্যাপ্লিকেশনটিতে ফায়ারবেস প্রমাণীকরণকে একীভূত করতে ব্যবসায়িক যুক্তি প্রয়োগ করবেন।

প্রদানকারীর সাথে ব্যবসায়িক যুক্তি

আপনি ব্যবহার করতে যাচ্ছি provider প্যাকেজ পাখির উইজেট অ্যাপ্লিকেশানের গাছ সর্বত্র একটি কেন্দ্রীভূত আবেদন রাষ্ট্র বস্তু উপলব্ধ করতে। সঙ্গে শুরু করার জন্য, উপরের আমদানির সংশোধন lib/main.dart :

lib/main.dart

import 'package:firebase_auth/firebase_auth.dart'; // new
import 'package:firebase_core/firebase_core.dart'; // new
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';           // new

import 'firebase_options.dart';                    // new
import 'src/authentication.dart';                  // new
import 'src/widgets.dart';

import লাইন Firebase কোর এবং প্রমাণীকরণ, এ টান পরিচয় করিয়ে provider প্যাকেজ যা আপনি আবেদন রাষ্ট্র বস্তুর উইজেট গাছ মাধ্যমে উপলব্ধ করা ব্যবহার করছেন, এবং থেকে প্রমাণীকরণ উইজেটগুলি অন্তর্ভুক্ত lib/src

এই অ্যাপ্লিকেশনটি রাষ্ট্র বস্তু, ApplicationState , এই পদক্ষেপ জন্য দুটি প্রধান দায়িত্ব আছে, কিন্তু হিসাবে আপনি পরে ধাপে আবেদন আরো ক্ষমতা যোগ অতিরিক্ত দায়িত্ব লাভ করবেন। প্রথম দায়িত্ব একটি কল সঙ্গে Firebase গ্রন্থাগার আরম্ভ হয় Firebase.initializeApp() , এবং তারপর সেখানে অনুমোদন প্রবাহ হ্যান্ডলিং হয়। শেষে নিম্নলিখিত বর্গ যোগ lib/main.dart :

lib/main.dart

class ApplicationState extends ChangeNotifier {
  ApplicationState() {
    init();
  }

  Future<void> init() async {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );

    FirebaseAuth.instance.userChanges().listen((user) {
      if (user != null) {
        _loginState = ApplicationLoginState.loggedIn;
      } else {
        _loginState = ApplicationLoginState.loggedOut;
      }
      notifyListeners();
    });
  }

  ApplicationLoginState _loginState = ApplicationLoginState.loggedOut;
  ApplicationLoginState get loginState => _loginState;

  String? _email;
  String? get email => _email;

  void startLoginFlow() {
    _loginState = ApplicationLoginState.emailAddress;
    notifyListeners();
  }

  Future<void> verifyEmail(
    String email,
    void Function(FirebaseAuthException e) errorCallback,
  ) async {
    try {
      var methods =
          await FirebaseAuth.instance.fetchSignInMethodsForEmail(email);
      if (methods.contains('password')) {
        _loginState = ApplicationLoginState.password;
      } else {
        _loginState = ApplicationLoginState.register;
      }
      _email = email;
      notifyListeners();
    } on FirebaseAuthException catch (e) {
      errorCallback(e);
    }
  }

  Future<void> signInWithEmailAndPassword(
    String email,
    String password,
    void Function(FirebaseAuthException e) errorCallback,
  ) async {
    try {
      await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: email,
        password: password,
      );
    } on FirebaseAuthException catch (e) {
      errorCallback(e);
    }
  }

  void cancelRegistration() {
    _loginState = ApplicationLoginState.emailAddress;
    notifyListeners();
  }

  Future<void> registerAccount(
      String email,
      String displayName,
      String password,
      void Function(FirebaseAuthException e) errorCallback) async {
    try {
      var credential = await FirebaseAuth.instance
          .createUserWithEmailAndPassword(email: email, password: password);
      await credential.user!.updateDisplayName(displayName);
    } on FirebaseAuthException catch (e) {
      errorCallback(e);
    }
  }

  void signOut() {
    FirebaseAuth.instance.signOut();
  }
}

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

এটি অবশ্যই উল্লেখ্য যে এটি FirebaseUI প্রমাণীকরণ প্রবাহের সম্পূর্ণ বাস্তবায়ন নয়, কারণ এটি একটি বিদ্যমান অ্যাকাউন্টের ব্যবহারকারীর ক্ষেত্রে পরিচালনা করে না যার লগ ইন করতে সমস্যা হচ্ছে৷ এই অতিরিক্ত ক্ষমতা প্রয়োগ করা একটি অনুশীলন হিসাবে বাকি অনুপ্রাণিত পাঠক।

প্রমাণীকরণ প্রবাহকে একীভূত করা

এখন আপনি আবেদন রাষ্ট্র শুরুর আছে এটা অ্যাপ্লিকেশন আরম্ভের মধ্যে আবেদন রাষ্ট্র তারের এবং মধ্যে প্রমাণীকরণ প্রবাহ যোগ করার জন্য সময় HomePage । প্রধান এন্ট্রি পয়েন্ট আপডেটের মাধ্যমে আবেদন রাষ্ট্র সংহত করতে provider প্যাকেজ:

lib/main.dart

void main() {
  // Modify from here
  runApp(
    ChangeNotifierProvider(
      create: (context) => ApplicationState(),
      builder: (context, _) => App(),
    ),
  );
  // to here.
}

থেকে পরিমার্জন main ফাংশন প্রদানকারী প্যাকেজ আবেদন রাষ্ট্র বস্তু শুরু করতে গিয়ে ব্যবহার করার জন্য দায়ী তোলে ChangeNotifierProvider উইজেট। আপনি এই নির্দিষ্ট প্রদানকারী বর্গ ব্যবহার করছেন কারণ আবেদন রাষ্ট্র বস্তু প্রসারিত ChangeNotifier এবং এই সম্ভব provider যখন জানতে নির্ভরশীল উইজেট আবার দেখাও প্যাকেজ। অবশেষে, সঙ্গে আবেদন রাষ্ট্র সংহত Authentication আপডেট করার মাধ্যমে HomePage এর build পদ্ধতি:

lib/main.dart

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Firebase Meetup'),
      ),
      body: ListView(
        children: <Widget>[
          Image.asset('assets/codelab.png'),
          const SizedBox(height: 8),
          const IconAndDetail(Icons.calendar_today, 'October 30'),
          const IconAndDetail(Icons.location_city, 'San Francisco'),
          // Add from here
          Consumer<ApplicationState>(
            builder: (context, appState, _) => Authentication(
              email: appState.email,
              loginState: appState.loginState,
              startLoginFlow: appState.startLoginFlow,
              verifyEmail: appState.verifyEmail,
              signInWithEmailAndPassword: appState.signInWithEmailAndPassword,
              cancelRegistration: appState.cancelRegistration,
              registerAccount: appState.registerAccount,
              signOut: appState.signOut,
            ),
          ),
          // to here
          const Divider(
            height: 8,
            thickness: 1,
            indent: 8,
            endIndent: 8,
            color: Colors.grey,
          ),
          const Header("What we'll be doing"),
          const Paragraph(
            'Join us for a day full of Firebase Workshops and Pizza!',
          ),
        ],
      ),
    );
  }
}

আপনি instantiate Authentication উইজেট, এবং একটি মধ্যে এটি মোড়ানো Consumer উইজেট। উপভোক্তা স্বাভাবিক ভাবেই উইজেট যে provider প্যাকেজ গাছ যখন আবেদন রাষ্ট্র পরিবর্তনের অংশ পুনর্নির্মাণের ব্যবহার করা যাবে। Authentication উইজেট প্রমাণীকরণ UI 'তে যে আপনি এখন পরিক্ষা করবে।

প্রমাণীকরণ প্রবাহ পরীক্ষা করা হচ্ছে

cdf2d25e436bd48d.png

এখানে প্রমাণীকরণ প্রবাহের শুরু, যেখানে ব্যবহারকারী ইমেল ফর্ম শুরু করতে RSVP বোতামে ট্যাপ করতে পারেন।

2a2cd6d69d172369.png

ইমেল প্রবেশ করার পরে, সিস্টেম নিশ্চিত করে যে ব্যবহারকারী ইতিমধ্যে নিবন্ধিত কিনা, এই ক্ষেত্রে ব্যবহারকারীকে একটি পাসওয়ার্ডের জন্য অনুরোধ করা হয়, বিকল্পভাবে যদি ব্যবহারকারী নিবন্ধিত না হয়, তাহলে তারা নিবন্ধন ফর্মের মাধ্যমে যান।

e5e65065dba36b54.png

ত্রুটি পরিচালনার প্রবাহ পরীক্ষা করতে একটি সংক্ষিপ্ত পাসওয়ার্ড (ছয়টি অক্ষরের কম) প্রবেশ করার চেষ্টা করুন। ব্যবহারকারী নিবন্ধিত হলে, তারা পরিবর্তে পাসওয়ার্ড দেখতে পাবেন।

fbb3ea35fb4f67a.png

এই পৃষ্ঠায় ত্রুটি হ্যান্ডলিং পরীক্ষা করতে ভুল পাসওয়ার্ড প্রবেশ করানো নিশ্চিত করুন৷ অবশেষে, একবার ব্যবহারকারী লগ ইন করলে, আপনি লগ ইন করার অভিজ্ঞতা দেখতে পাবেন যা ব্যবহারকারীকে আবার লগ আউট করার ক্ষমতা দেয়।

4ed811a25b0cf816.png

এবং এর সাথে, আপনি একটি প্রমাণীকরণ প্রবাহ বাস্তবায়ন করেছেন। অভিনন্দন!

6. ক্লাউড ফায়ারস্টোরে বার্তা লিখুন

ব্যবহারকারীরা আসছেন জেনে দারুণ, কিন্তু অ্যাপটিতে অতিথিদের অন্য কিছু করার সুযোগ দেওয়া যাক। যদি তারা একটি গেস্টবুকে বার্তা ছেড়ে যেতে পারে? তারা ভাগ করে নিতে পারে কেন তারা আসতে আগ্রহী বা তারা কার সাথে দেখা করতে চায়।

বার্তা ব্যবহারকারীরা অ্যাপ্লিকেশানে লিখতে চ্যাট সংরক্ষণ করতে, আপনাকে ব্যবহার করব ক্লাউড Firestore

তথ্য মডেল

ক্লাউড ফায়ারস্টোর হল একটি NoSQL ডাটাবেস, এবং ডাটাবেসে সংরক্ষিত ডেটা সংগ্রহ, নথি, ক্ষেত্র এবং উপ-সংগ্রহে বিভক্ত। আপনি একটি টপ লেভেল সংগ্রহ নামক একটি নথি হিসাবে চ্যাট প্রত্যেক বার্তার সংরক্ষণ করবে guestbook

7c20dc8424bb1d84.png

Firestore এ বার্তা যোগ করুন

এই বিভাগে, আপনি ডাটাবেসে নতুন বার্তা লিখতে ব্যবহারকারীদের জন্য কার্যকারিতা যোগ করবেন। প্রথমে, আপনি UI উপাদানগুলি (ফর্ম ক্ষেত্র এবং পাঠান বোতাম) যোগ করেন এবং তারপরে আপনি কোডটি যুক্ত করেন যা এই উপাদানগুলিকে ডাটাবেসের সাথে সংযুক্ত করে।

প্রথমত, জন্য আমদানি যোগ cloud_firestore প্যাকেজ এবং dart:async

lib/main.dart

import 'dart:async';                                    // new

import 'package:cloud_firestore/cloud_firestore.dart';  // new
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';

import 'firebase_options.dart';
import 'src/authentication.dart';
import 'src/widgets.dart';

কে একটি বার্তা ক্ষেত্র এবং একটি সেন্ড বাটন এর UI উপাদান গঠন করা, উইজেট একটি নতুন stateful যোগ GuestBook নীচে lib/main.dart

lib/main.dart

class GuestBook extends StatefulWidget {
  const GuestBook({required this.addMessage});
  final FutureOr<void> Function(String message) addMessage;

  @override
  _GuestBookState createState() => _GuestBookState();
}

class _GuestBookState extends State<GuestBook> {
  final _formKey = GlobalKey<FormState>(debugLabel: '_GuestBookState');
  final _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Form(
        key: _formKey,
        child: Row(
          children: [
            Expanded(
              child: TextFormField(
                controller: _controller,
                decoration: const InputDecoration(
                  hintText: 'Leave a message',
                ),
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Enter your message to continue';
                  }
                  return null;
                },
              ),
            ),
            const SizedBox(width: 8),
            StyledButton(
              onPressed: () async {
                if (_formKey.currentState!.validate()) {
                  await widget.addMessage(_controller.text);
                  _controller.clear();
                }
              },
              child: Row(
                children: const [
                  Icon(Icons.send),
                  SizedBox(width: 4),
                  Text('SEND'),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

এখানে আগ্রহের কয়েকটি পয়েন্ট আছে। প্রথমত, আপনি একটি ফর্ম ইনস্ট্যান্টিশিয়েট করছেন যাতে upi বার্তাটি প্রকৃতপক্ষে কিছু বিষয়বস্তু আছে তা যাচাই করতে পারে এবং ব্যবহারকারীকে একটি ত্রুটির বার্তা দেখাতে পারে যদি কোনটি না থাকে। পথ একটি ফর্ম যাচাই করতে ফর্ম পিছনে ফর্ম রাষ্ট্র অ্যাক্সেস জড়িত থাকে, এবং এই জন্য আপনি একটি ব্যবহার GlobalKey । কীগুলি আরো তথ্যের জন্য, এবং কিভাবে তাদের ব্যবহার করার জন্য, দয়া করে দেখুন পাখির উইজেট 101 পর্ব "যখন না ব্যবহার কী করতে"

এছাড়াও পথ উইজেট পরিপূর্ণ হয় মনে রাখবেন, আপনি একটি আছে Row একটি সঙ্গে, TextFormField এবং StyledButton , যা নিজেই একটি রয়েছে Row । এছাড়াও মনে রাখবেন TextFormField একটি জড়িয়ে রাখা হয়েছে Expanded উইজেট, এই বাহিনী TextFormField সারিতে কোনো অতিরিক্ত জায়গা নিয়ে করা। ভালোভাবে বুঝতে এই কেন প্রয়োজন হয়, মাধ্যমে পড়া দয়া বোঝাপড়া সীমাবদ্ধতার

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

const Header("What we'll be doing"),
const Paragraph(
  'Join us for a day full of Firebase Workshops and Pizza!',
),
// Add the following two lines.
const Header('Discussion'),
GuestBook(addMessage: (message) => print(message)),

যদিও এটি উইজেট প্রদর্শনের জন্য যথেষ্ট, এটি দরকারী কিছু করার জন্য যথেষ্ট নয়। আপনি খুব শীঘ্রই এই কোডটিকে কার্যকরী করতে আপডেট করবেন৷

অ্যাপের পূর্বরূপ

পাঠান বাটন ক্লিক একজন ব্যবহারকারী নিচের কোড স্নিপেট আরম্ভ হবে। এটা তোলে বার্তা ইনপুট ক্ষেত্র বিষয়বস্তু যোগ guestbook ডেটাবেসের সংগ্রহ। বিশেষ করে, addMessageToGuestBook পদ্ধতি বার্তাটি একটি নতুন দস্তাবেজে (একটি স্বয়ংক্রিয়ভাবে উত্পন্ন আইডি দিয়ে) এর বিষয়বস্তু যোগ guestbook সংগ্রহ।

মনে রাখবেন যে, FirebaseAuth.instance.currentUser.uid স্বয়ংক্রিয়ভাবে তৈরি অনন্য আইডি একটি রেফারেন্স যে Firebase প্রমাণীকরণের জন্য সব লগ-ইন করা ব্যবহারকারীরা দেয়।

আরেকটি ইতিবাচক পরিবর্তন আনুন lib/main.dart ফাইল। যোগ addMessageToGuestBook পদ্ধতি। আপনি পরবর্তী ধাপে ইউজার ইন্টারফেস এবং এই ক্ষমতা একসাথে সংযুক্ত করবেন।

lib/main.dart

class ApplicationState extends ChangeNotifier {

  // Current content of ApplicationState elided ...

  // Add from here
  Future<DocumentReference> addMessageToGuestBook(String message) {
    if (_loginState != ApplicationLoginState.loggedIn) {
      throw Exception('Must be logged in');
    }

    return FirebaseFirestore.instance
        .collection('guestbook')
        .add(<String, dynamic>{
      'text': message,
      'timestamp': DateTime.now().millisecondsSinceEpoch,
      'name': FirebaseAuth.instance.currentUser!.displayName,
      'userId': FirebaseAuth.instance.currentUser!.uid,
    });
  }
  // To here
}

ডাটাবেসের মধ্যে UI এর ওয়্যারিং

আপনার কাছে একটি UI আছে যেখানে ব্যবহারকারী অতিথি বইতে যোগ করতে চান এমন পাঠ্য লিখতে পারেন এবং ক্লাউড ফায়ারস্টোরে এন্ট্রি যোগ করার জন্য আপনার কাছে কোড রয়েছে। এখন আপনাকে যা করতে হবে তা হল দুটিকে একসাথে সংযুক্ত করা। ইন lib/main.dart নিম্নলিখিত পরিবর্তন করতে HomePage উইজেট।

lib/main.dart

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Firebase Meetup'),
      ),
      body: ListView(
        children: <Widget>[
          Image.asset('assets/codelab.png'),
          const SizedBox(height: 8),
          const IconAndDetail(Icons.calendar_today, 'October 30'),
          const IconAndDetail(Icons.location_city, 'San Francisco'),
          Consumer<ApplicationState>(
            builder: (context, appState, _) => Authentication(
              email: appState.email,
              loginState: appState.loginState,
              startLoginFlow: appState.startLoginFlow,
              verifyEmail: appState.verifyEmail,
              signInWithEmailAndPassword: appState.signInWithEmailAndPassword,
              cancelRegistration: appState.cancelRegistration,
              registerAccount: appState.registerAccount,
              signOut: appState.signOut,
            ),
          ),
          const Divider(
            height: 8,
            thickness: 1,
            indent: 8,
            endIndent: 8,
            color: Colors.grey,
          ),
          const Header("What we'll be doing"),
          const Paragraph(
            'Join us for a day full of Firebase Workshops and Pizza!',
          ),
          // Modify from here
          Consumer<ApplicationState>(
            builder: (context, appState, _) => Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                if (appState.loginState == ApplicationLoginState.loggedIn) ...[
                  const Header('Discussion'),
                  GuestBook(
                    addMessage: (message) =>
                        appState.addMessageToGuestBook(message),
                  ),
                ],
              ],
            ),
          ),
          // To here.
        ],
      ),
    );
  }
}

এই ধাপের শুরুতে আপনি যে দুটি লাইন যোগ করেছেন তা সম্পূর্ণ বাস্তবায়নের সাথে প্রতিস্থাপন করেছেন। আপনি আবার ব্যবহার করছেন Consumer<ApplicationState> আবেদন রাষ্ট্র গাছ আপনি রেন্ডারিং করছে অংশ উপলব্ধ করতে। এটি আপনাকে UI-তে একটি বার্তা প্রবেশকারী কেউ প্রতিক্রিয়া জানাতে এবং এটি ডাটাবেসে প্রকাশ করতে সক্ষম করে। পরবর্তী বিভাগে আপনি পরীক্ষা করবেন যে যোগ করা বার্তাগুলি ডাটাবেসে প্রকাশিত হয়েছে কিনা।

বার্তা পাঠানোর পরীক্ষা করুন

  1. আপনি অ্যাপে সাইন ইন করেছেন তা নিশ্চিত করুন।
  2. যেমন "আরে!" যেমন একটি বার্তা লিখুন, এবং তারপর সেন্ড ক্লিক করুন।

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

কিন্তু আপনি Firebase কনসোলে নতুন যোগ করা বার্তাটি দেখতে পারেন।

Firebase কনসোলে, এ ডাটাবেজ ড্যাশবোর্ড , আপনি দেখতে পাবেন guestbook আপনার নতুন যোগ বার্তা সঙ্গে সংগ্রহ। আপনি যদি বার্তা পাঠাতে থাকেন, আপনার গেস্টবুক সংগ্রহে অনেক নথি থাকবে, যেমন:

ফায়ারবেস কনসোল

713870af0b3b63c.png

7. বার্তা পড়ুন

এটা চমৎকার যে অতিথিরা ডাটাবেসে বার্তা লিখতে পারে, কিন্তু তারা এখনও অ্যাপে সেগুলি দেখতে পায় না। এর ঠিক করা যাক!

বার্তা সিঙ্ক্রোনাইজ করুন

বার্তাগুলি প্রদর্শন করতে, আপনাকে এমন শ্রোতাদের যোগ করতে হবে যা ডেটা পরিবর্তনের সময় ট্রিগার করে এবং তারপরে একটি UI উপাদান তৈরি করে যা নতুন বার্তাগুলি দেখায়। আপনি অ্যাপ্লিকেশন রাজ্যে কোড যোগ করবেন যা অ্যাপ থেকে নতুন যোগ করা বার্তাগুলির জন্য শোনে।

শুধুমাত্র উপরের GuestBook নিম্নলিখিত মান বর্গ উইজেট। এই ক্লাসটি ক্লাউড ফায়ারস্টোরে আপনি যে ডেটা সংরক্ষণ করছেন তার একটি কাঠামোগত দৃশ্য প্রকাশ করে৷

lib/main.dart

class GuestBookMessage {
  GuestBookMessage({required this.name, required this.message});
  final String name;
  final String message;
}

বিভাগে ApplicationState যেখানে আপনি রাষ্ট্র এবং getters নির্ধারণ করুন, নতুন লাইন নিম্নলিখিত যোগ করুন:

lib/main.dart

  ApplicationLoginState _loginState = ApplicationLoginState.loggedOut;
  ApplicationLoginState get loginState => _loginState;

  String? _email;
  String? get email => _email;

  // Add from here
  StreamSubscription<QuerySnapshot>? _guestBookSubscription;
  List<GuestBookMessage> _guestBookMessages = [];
  List<GuestBookMessage> get guestBookMessages => _guestBookMessages;
  // to here.

এবং পরিশেষে, আরম্ভের বিভাগে ApplicationState , ডকুমেন্ট সংগ্রহ উপর একটি ক্যোয়ারী সাবস্ক্রাইব করার জন্য যখন কোনো ব্যবহারকারী লগ, এবং আনসাবস্ক্রাইব যখন তারা লগ আউট নিম্নলিখিত যোগ করুন।

lib/main.dart

  Future<void> init() async {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );

    FirebaseAuth.instance.userChanges().listen((user) {
      if (user != null) {
        _loginState = ApplicationLoginState.loggedIn;
        // Add from here
        _guestBookSubscription = FirebaseFirestore.instance
            .collection('guestbook')
            .orderBy('timestamp', descending: true)
            .snapshots()
            .listen((snapshot) {
          _guestBookMessages = [];
          for (final document in snapshot.docs) {
            _guestBookMessages.add(
              GuestBookMessage(
                name: document.data()['name'] as String,
                message: document.data()['text'] as String,
              ),
            );
          }
          notifyListeners();
        });
        // to here.
      } else {
        _loginState = ApplicationLoginState.loggedOut;
        // Add from here
        _guestBookMessages = [];
        _guestBookSubscription?.cancel();
        // to here.
      }
      notifyListeners();
    });
  }

এই বিভাগে গুরুত্বপূর্ণ, এখানে যেখানে তোমাদের উপর একটি ক্যোয়ারী গঠন করা guestbook সংগ্রহ, এবং হাতল সাবস্ক্রাইব করতে এবং এই সংগ্রহে আন-সাবস্ক্রাইব। আপনি স্ট্রিম, যেখানে আপনি বার্তার একটি স্থানীয় ক্যাশে পুনর্গঠনে শুনতে guestbook সংগ্রহ, এবং যাতে আপনি এটি থেকে পরে ত্যাগ করতে পারেন এছাড়াও এই সদস্যতার একটি রেফারেন্স সংরক্ষণ করি। এখানে অনেক কিছু চলছে, এবং একটি পরিষ্কার মানসিক মডেল পেতে হলে কী ঘটে তা পরিদর্শন করার জন্য ডিবাগারে কিছু সময় ব্যয় করা মূল্যবান।

আরো তথ্যের জন্য, দেখুন ক্লাউড Firestore ডকুমেন্টেশন

ইন GuestBook আপনি ব্যবহারকারীর ইন্টারফেসে পরিবর্তন রাষ্ট্র সংযোগ করতে হবে উইজেট। আপনি উইজেটটির কনফিগারেশনের অংশ হিসাবে বার্তাগুলির একটি তালিকা যোগ করে পরিবর্তন করুন।

lib/main.dart

class GuestBook extends StatefulWidget {
  // Modify the following line
  const GuestBook({required this.addMessage, required this.messages});
  final FutureOr<void> Function(String message) addMessage;
  final List<GuestBookMessage> messages; // new

  @override
  _GuestBookState createState() => _GuestBookState();
}

এর পরে, আমরা এই নতুন কনফিগারেশন এক্সপোজ _GuestBookState পরিবর্তন করে build পদ্ধতি নিম্নরূপ।

lib/main.dart

class _GuestBookState extends State<GuestBook> {
  final _formKey = GlobalKey<FormState>(debugLabel: '_GuestBookState');
  final _controller = TextEditingController();

  @override
  // Modify from here
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // to here.
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: Form(
            key: _formKey,
            child: Row(
              children: [
                Expanded(
                  child: TextFormField(
                    controller: _controller,
                    decoration: const InputDecoration(
                      hintText: 'Leave a message',
                    ),
                    validator: (value) {
                      if (value == null || value.isEmpty) {
                        return 'Enter your message to continue';
                      }
                      return null;
                    },
                  ),
                ),
                const SizedBox(width: 8),
                StyledButton(
                  onPressed: () async {
                    if (_formKey.currentState!.validate()) {
                      await widget.addMessage(_controller.text);
                      _controller.clear();
                    }
                  },
                  child: Row(
                    children: const [
                      Icon(Icons.send),
                      SizedBox(width: 4),
                      Text('SEND'),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
        // Modify from here
        const SizedBox(height: 8),
        for (var message in widget.messages)
          Paragraph('${message.name}: ${message.message}'),
        const SizedBox(height: 8),
      ],
      // to here.
    );
  }
}

আপনি একটি সঙ্গে বিল্ড পদ্ধতি পূর্ববর্তী বিষয়বস্তু মোড়ানো Column এর লেঙ্গুড় এ উইজেট, এবং তারপর Column এর শিশু আপনি একটি যোগ সংগ্রহের জন্য একটি নতুন জেনারেট করতে Paragraph বার্তা তালিকার প্রতিটি বার্তার জন্য।

অবশেষে, আপনি এখন লাশ আপডেট করা দরকার HomePage সঠিকভাবে গঠন করা GuestBook নতুন messages প্যারামিটার।

lib/main.dart

Consumer<ApplicationState>(
  builder: (context, appState, _) => Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      if (appState.loginState == ApplicationLoginState.loggedIn) ...[
        const Header('Discussion'),
        GuestBook(
          addMessage: (message) =>
              appState.addMessageToGuestBook(message),
          messages: appState.guestBookMessages, // new
        ),
      ],
    ],
  ),
),

সিঙ্ক্রোনাইজিং বার্তা পরীক্ষা করুন

ক্লাউড ফায়ারস্টোর ডাটাবেসে সাবস্ক্রাইব করা ক্লায়েন্টদের সাথে স্বয়ংক্রিয়ভাবে এবং তাত্ক্ষণিকভাবে ডেটা সিঙ্ক্রোনাইজ করে।

  1. আপনি ডাটাবেসে আগে তৈরি করা বার্তাগুলি অ্যাপে প্রদর্শিত হওয়া উচিত। নতুন বার্তা লিখতে নির্দ্বিধায়; তারা অবিলম্বে প্রদর্শিত উচিত.
  2. আপনি একাধিক উইন্ডো বা ট্যাবে আপনার ওয়ার্কস্পেস খুললে, ট্যাব জুড়ে রিয়েল টাইমে বার্তাগুলি সিঙ্ক হবে৷
  3. (ঐচ্ছিক) আপনি নিজে, মুছে ফেলা পরিবর্তন, বা Firebase কনসোলের ডাটাবেস বিভাগে সরাসরি নতুন বার্তা যোগ করার চেষ্টা করতে পারেন; যেকোন পরিবর্তন UI এ উপস্থিত হওয়া উচিত।

অভিনন্দন! আপনি আপনার অ্যাপে ক্লাউড ফায়ারস্টোর ডকুমেন্ট পড়ছেন!

অ্যাপ পি পর্যালোচনা

8. মৌলিক নিরাপত্তা নিয়ম সেট আপ করুন

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

নিরাপত্তা বিধি আপনাকে আপনার ডাটাবেসের নথি এবং সংগ্রহগুলিতে অ্যাক্সেস নিয়ন্ত্রণ করতে দেয়। নমনীয় নিয়ম সিনট্যাক্স আপনাকে এমন নিয়ম তৈরি করতে দেয় যা সমস্ত লেখা থেকে শুরু করে সম্পূর্ণ ডাটাবেস থেকে একটি নির্দিষ্ট নথিতে ক্রিয়াকলাপের সাথে মেলে।

আপনি Firebase কনসোলে ক্লাউড ফায়ারস্টোরের জন্য নিরাপত্তা নিয়ম লিখতে পারেন:

  1. Firebase কনসোলের বিকাশ বিভাগে, ডাটাবেজ ক্লিক করুন, এবং তারপর বিধি ট্যাব নির্বাচন করুন (অথবা এখানে ক্লিক করুন বিধি ট্যাবে সরাসরি যেতে)।
  2. আপনি নিম্নলিখিত ডিফল্ট সুরক্ষা নিয়মগুলি দেখতে পাবেন, সেই সাথে নিয়মগুলি সর্বজনীন হওয়ার বিষয়ে একটি সতর্কতা সহ।

7767a2d2e64e7275.png

সংগ্রহ সনাক্ত করুন

প্রথমত, অ্যাপটি যে সংগ্রহগুলিতে ডেটা লেখে তা চিহ্নিত করুন।

ইন match /databases/{database}/documents , সংগ্রহ আপনি নিরাপদ করার জন্য চাই যে চিহ্নিত:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
     // You'll add rules here in the next step.
  }
}

নিরাপত্তা নিয়ম যোগ করুন

যেহেতু আপনি প্রতিটি গেস্টবুক নথিতে একটি ক্ষেত্র হিসাবে প্রমাণীকরণ UID ব্যবহার করেছেন, আপনি প্রমাণীকরণ UID পেতে পারেন এবং যাচাই করতে পারেন যে যে কেউ নথিতে লেখার চেষ্টা করছেন তার একটি মিলিত প্রমাণীকরণ UID আছে।

নীচে দেখানো হিসাবে আপনার নিয়ম সেটে পড়ার এবং লেখার নিয়মগুলি যুক্ত করুন:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      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}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow write:
      if request.auth.uid == request.resource.data.userId
          && "name" in request.resource.data
          && "text" in request.resource.data
          && "timestamp" in request.resource.data;
    }
  }
}

9. বোনাস ধাপ: আপনি যা শিখেছেন তা অনুশীলন করুন

একজন অংশগ্রহণকারীর আরএসভিপি স্ট্যাটাস রেকর্ড করুন

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

আপনি অ্যাপ্লিকেশন স্টেটে কয়েকটি নতুন ক্ষমতা যুক্ত করতে যাচ্ছেন। প্রথমটি হল লগ ইন করা ব্যবহারকারীর জন্য মনোনীত করার ক্ষমতা যদি তারা উপস্থিত থাকে বা না থাকে। দ্বিতীয় ক্ষমতা হল কতজন লোক আসলে উপস্থিত হচ্ছে তার কাউন্টার।

ইন lib/main.dart , এই রাষ্ট্র সাথে যোগাযোগ করার জন্য UI 'তে কোড সক্ষম করতে accessors বিভাগে নিম্নলিখিত যোগ করুন:

lib/main.dart

int _attendees = 0;
int get attendees => _attendees;

Attending _attending = Attending.unknown;
StreamSubscription<DocumentSnapshot>? _attendingSubscription;
Attending get attending => _attending;
set attending(Attending attending) {
  final userDoc = FirebaseFirestore.instance
      .collection('attendees')
      .doc(FirebaseAuth.instance.currentUser!.uid);
  if (attending == Attending.yes) {
    userDoc.set(<String, dynamic>{'attending': true});
  } else {
    userDoc.set(<String, dynamic>{'attending': false});
  }
}

আপডেট ApplicationState এর init পদ্ধতি নিম্নরূপ:

lib/main.dart

  Future<void> init() async {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );

    // Add from here
    FirebaseFirestore.instance
        .collection('attendees')
        .where('attending', isEqualTo: true)
        .snapshots()
        .listen((snapshot) {
      _attendees = snapshot.docs.length;
      notifyListeners();
    });
    // To here

    FirebaseAuth.instance.userChanges().listen((user) {
      if (user != null) {
        _loginState = ApplicationLoginState.loggedIn;
        _guestBookSubscription = FirebaseFirestore.instance
            .collection('guestbook')
            .orderBy('timestamp', descending: true)
            .snapshots()
            .listen((snapshot) {
          _guestBookMessages = [];
          for (final document in snapshot.docs) {
            _guestBookMessages.add(
              GuestBookMessage(
                name: document.data()['name'] as String,
                message: document.data()['text'] as String,
              ),
            );
          }
          notifyListeners();
        });
        // Add from here
        _attendingSubscription = FirebaseFirestore.instance
            .collection('attendees')
            .doc(user.uid)
            .snapshots()
            .listen((snapshot) {
          if (snapshot.data() != null) {
            if (snapshot.data()!['attending'] as bool) {
              _attending = Attending.yes;
            } else {
              _attending = Attending.no;
            }
          } else {
            _attending = Attending.unknown;
          }
          notifyListeners();
        });
        // to here
      } else {
        _loginState = ApplicationLoginState.loggedOut;
        _guestBookMessages = [];
        _guestBookSubscription?.cancel();
        _attendingSubscription?.cancel(); // new
      }
      notifyListeners();
    });
  }

উপরে একটি সর্বদা সাবস্ক্রাইব করা ক্যোয়ারী যোগ করে উপস্থিতদের সংখ্যা খুঁজে বের করার জন্য, এবং একটি দ্বিতীয় ক্যোয়ারী যেটি শুধুমাত্র সক্রিয় থাকে যখন একজন ব্যবহারকারী লগইন করে থাকে কিনা তা খুঁজে বের করতে। এর পরে, পরে নিম্নলিখিত শুমার যোগ GuestBookMessage ঘোষণা:

lib/main.dart

enum Attending { yes, no, unknown }

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

lib/main.dart

class YesNoSelection extends StatelessWidget {
  const YesNoSelection({required this.state, required this.onSelection});
  final Attending state;
  final void Function(Attending selection) onSelection;

  @override
  Widget build(BuildContext context) {
    switch (state) {
      case Attending.yes:
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: [
              ElevatedButton(
                style: ElevatedButton.styleFrom(elevation: 0),
                onPressed: () => onSelection(Attending.yes),
                child: const Text('YES'),
              ),
              const SizedBox(width: 8),
              TextButton(
                onPressed: () => onSelection(Attending.no),
                child: const Text('NO'),
              ),
            ],
          ),
        );
      case Attending.no:
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: [
              TextButton(
                onPressed: () => onSelection(Attending.yes),
                child: const Text('YES'),
              ),
              const SizedBox(width: 8),
              ElevatedButton(
                style: ElevatedButton.styleFrom(elevation: 0),
                onPressed: () => onSelection(Attending.no),
                child: const Text('NO'),
              ),
            ],
          ),
        );
      default:
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: [
              StyledButton(
                onPressed: () => onSelection(Attending.yes),
                child: const Text('YES'),
              ),
              const SizedBox(width: 8),
              StyledButton(
                onPressed: () => onSelection(Attending.no),
                child: const Text('NO'),
              ),
            ],
          ),
        );
    }
  }
}

পরবর্তী, আপনি আপডেট করতে হবে HomePage 's বিল্ড পদ্ধতি সুবিধা গ্রহণ করতে YesNoSelection একটি মনোনয়ন করার ব্যবহারকারী লগ ইন যদি তারা অংশগ্রহণ করছেন সক্রিয়। আপনি এই ইভেন্টে অংশগ্রহণকারীদের সংখ্যাও প্রদর্শন করবেন।

lib/main.dart

Consumer<ApplicationState>(
  builder: (context, appState, _) => Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      // Add from here
      if (appState.attendees >= 2)
        Paragraph('${appState.attendees} people going')
      else if (appState.attendees == 1)
        const Paragraph('1 person going')
      else
        const Paragraph('No one going'),
      // To here.
      if (appState.loginState == ApplicationLoginState.loggedIn) ...[
        // Add from here
        YesNoSelection(
          state: appState.attending,
          onSelection: (attending) => appState.attending = attending,
        ),
        // To here.
        const Header('Discussion'),
        GuestBook(
          addMessage: (message) =>
              appState.addMessageToGuestBook(message),
          messages: appState.guestBookMessages,
        ),
      ],
    ],
  ),
),

নিয়ম যোগ করুন

যেহেতু আপনি ইতিমধ্যে কিছু নিয়ম সেট আপ করেছেন, আপনি বোতামগুলির সাথে যে নতুন ডেটা যোগ করছেন তা প্রত্যাখ্যান করা হবে৷ আপনি নিয়মটি আপডেট করার জন্য যোগ করার জন্য প্রয়োজন হবে attendees সংগ্রহ।

জন্য attendees সংগ্রহ, যেহেতু আপনি নথিতে নামের প্রমাণীকরণ ইউআইডি ব্যবহৃত, আপনি এটি দখল এবং যাচাই করুন যে জমাকারীর করতে uid ডকুমেন্ট তারা লিখছেন সমান। আপনি প্রত্যেককে অংশগ্রহণকারীদের তালিকা পড়ার অনুমতি দেবেন (যেহেতু সেখানে কোনও ব্যক্তিগত ডেটা নেই), তবে শুধুমাত্র নির্মাতা এটি আপডেট করতে সক্ষম হবেন।

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId;
    }
  }
}

বৈধতা নিয়ম যোগ করুন

সমস্ত প্রত্যাশিত ক্ষেত্র নথিতে উপস্থিত রয়েছে তা নিশ্চিত করতে ডেটা যাচাইকরণ যোগ করুন:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId
          && "attending" in request.resource.data;

    }
  }
}

(ঐচ্ছিক) আপনি এখন বোতাম ক্লিক ফলাফল দেখতে পারেন। Firebase কনসোলে আপনার ক্লাউড ফায়ারস্টোর ড্যাশবোর্ডে যান।

অ্যাপের পূর্বরূপ

10. অভিনন্দন!

আপনি একটি ইন্টারেক্টিভ, রিয়েল-টাইম ওয়েব অ্যাপ্লিকেশন তৈরি করতে Firebase ব্যবহার করেছেন!

আমরা কভার করেছি কি

  • ফায়ারবেস প্রমাণীকরণ
  • ক্লাউড ফায়ারস্টোর
  • ফায়ারবেস নিরাপত্তা নিয়ম

পরবর্তী পদক্ষেপ

  • অন্যান্য Firebase পণ্য সম্পর্কে আরও জানতে চান? হয়তো আপনি ইমেজ ফাইল সংরক্ষণ করতে চান যে ব্যবহারকারীরা আপলোড? অথবা আপনার ব্যবহারকারীদের বিজ্ঞপ্তি পাঠান? পরীক্ষা করে দেখুন Firebase ডকুমেন্টেশন । Firebase এর জন্য Flutter প্লাগইন সম্পর্কে আরও জানতে চান? পরীক্ষা করে দেখুন FlutterFire আরও তথ্যের জন্য।
  • ক্লাউড ফায়ারস্টোর সম্পর্কে আরও জানতে চান? হয়তো আপনি উপসংগ্রহ এবং লেনদেন সম্পর্কে জানতে চান? উপর আগাইয়া ক্লাউড Firestore ওয়েব codelab একটি codelab হল ক্লাউড Firestore উপর আরো গভীরতা মধ্যে যায় জন্য। অথবা এই খুঁজে বার করো ইউটিউব সিরিজ জানেন যে মেঘ Firestore পেতে !

আরও জানুন

কেমন যাচ্ছে?

আমরা আপনার প্রতিক্রিয়া চাই! একটি (খুব) শর্ট ফর্মটি পূরণ করুন এখানে