১. শুরু করার আগে
এই কোডল্যাবে, আপনি অ্যান্ড্রয়েড এবং আইওএসের জন্য ফ্লটার মোবাইল অ্যাপ তৈরি করার জন্য ফায়ারবেসের কিছু মৌলিক বিষয় শিখবেন।
পূর্বশর্ত
- ফ্লটারের সাথে পরিচিতি
- ফ্লাটার এসডিকে
- আপনার পছন্দের একটি টেক্সট এডিটর
তুমি কি শিখবে
- Flutter ব্যবহার করে Android, iOS, ওয়েব এবং macOS-এ কীভাবে একটি ইভেন্ট RSVP এবং গেস্টবুক চ্যাট অ্যাপ তৈরি করবেন।
- Firebase Authentication ব্যবহার করে ব্যবহারকারীদের কীভাবে প্রমাণীকরণ করবেন এবং Firestore এর সাথে ডেটা সিঙ্ক করবেন।
|
|
|
|
তোমার যা লাগবে
নিম্নলিখিত ডিভাইসগুলির যেকোনো একটি:
- আপনার কম্পিউটারের সাথে সংযুক্ত একটি বাস্তব Android বা iOS ডিভাইস এবং ডেভেলপার মোডে সেট করা আছে।
- iOS সিমুলেটর ( Xcode টুল প্রয়োজন)।
- অ্যান্ড্রয়েড এমুলেটর ( অ্যান্ড্রয়েড স্টুডিওতে সেটআপ প্রয়োজন)।
আপনার নিম্নলিখিতগুলিও প্রয়োজন:
- আপনার পছন্দের একটি ব্রাউজার, যেমন গুগল ক্রোম।
- আপনার পছন্দের একটি IDE বা টেক্সট এডিটর যা ডার্ট এবং ফ্লাটার প্লাগইন দিয়ে কনফিগার করা হয়েছে, যেমন অ্যান্ড্রয়েড স্টুডিও বা ভিজ্যুয়াল স্টুডিও কোড ।
- যদি আপনি প্রান্তে বসবাস উপভোগ করেন, তাহলে Flutter অথবা
betaএর সর্বশেষstableসংস্করণ। - আপনার Firebase প্রকল্প তৈরি এবং পরিচালনার জন্য একটি Google অ্যাকাউন্ট।
-
FirebaseCLI আপনার Google অ্যাকাউন্টে লগ ইন করেছে।
2. নমুনা কোড পান
GitHub থেকে আপনার প্রকল্পের প্রাথমিক সংস্করণটি ডাউনলোড করুন:
- কমান্ড লাইন থেকে, GitHub রিপোজিটরিটি
flutter-codelabsডিরেক্টরিতে ক্লোন করুন:
git clone https://github.com/flutter/codelabs.git flutter-codelabs
flutter-codelabs ডিরেক্টরিতে কোডল্যাবের একটি সংগ্রহের কোড রয়েছে। এই কোডল্যাবের কোডটি flutter-codelabs/firebase-get-to-know-flutter ডিরেক্টরিতে রয়েছে। ডিরেক্টরিতে স্ন্যাপশটের একটি সিরিজ রয়েছে যা দেখায় যে প্রতিটি ধাপের শেষে আপনার প্রকল্পটি কেমন হওয়া উচিত। উদাহরণস্বরূপ, আপনি দ্বিতীয় ধাপে আছেন।
- দ্বিতীয় ধাপের জন্য মিলে যাওয়া ফাইলগুলি খুঁজুন:
cd flutter-codelabs/firebase-get-to-know-flutter/step_02
যদি আপনি সামনের দিকে এগিয়ে যেতে চান অথবা কোন ধাপের পরে কোন কিছু কেমন দেখাবে তা দেখতে চান, তাহলে আপনার আগ্রহের ধাপের নামানুসারে তৈরি ডিরেক্টরিতে দেখুন।
স্টার্টার অ্যাপটি আমদানি করুন
- আপনার পছন্দের IDE-তে
flutter-codelabs/firebase-get-to-know-flutter/step_02ডিরেক্টরিটি খুলুন বা আমদানি করুন। এই ডিরেক্টরিতে কোডল্যাবের জন্য স্টার্টার কোড রয়েছে, যার মধ্যে একটি এখনও কার্যকর নয় এমন ফ্লটার মিটআপ অ্যাপ রয়েছে। যখন আপনি আপনার IDE-তে অ্যাপটি খুলবেন, তখন আপনি কম্পাইল টাইম ত্রুটিগুলি লক্ষ্য করবেন যা ধাপ 4-এ ঠিক করা হবে।
যেসব ফাইলের কাজ প্রয়োজন সেগুলো খুঁজে বের করুন
এই অ্যাপের কোডটি একাধিক ডিরেক্টরিতে ছড়িয়ে আছে। কার্যকারিতার এই বিভাজন কাজটিকে আরও সহজ করে তোলে কারণ এটি কার্যকারিতা অনুসারে কোডগুলিকে গোষ্ঠীভুক্ত করে।
- নিম্নলিখিত ফাইলগুলি সনাক্ত করুন:
-
lib/main.dart: এই ফাইলটিতে প্রধান এন্ট্রি পয়েন্ট এবং অ্যাপ উইজেট রয়েছে। -
lib/home_page.dart: এই ফাইলটিতে হোম পেজ উইজেট রয়েছে। -
lib/src/widgets.dart: এই ফাইলটিতে অ্যাপের স্টাইলকে স্ট্যান্ডার্ডাইজ করার জন্য কিছু উইজেট রয়েছে। এগুলো স্টার্টার অ্যাপের স্ক্রিন তৈরি করে। -
lib/src/authentication.dart: এই ফাইলটিতে Firebase ইমেল-ভিত্তিক প্রমাণীকরণের জন্য লগইন ব্যবহারকারীর অভিজ্ঞতা তৈরি করার জন্য উইজেটের একটি সেট সহ প্রমাণীকরণের আংশিক বাস্তবায়ন রয়েছে। প্রমাণীকরণ প্রবাহের জন্য এই উইজেটগুলি এখনও স্টার্টার অ্যাপে ব্যবহৃত হয়নি, তবে আপনি শীঘ্রই এগুলি যুক্ত করবেন।
-
বাকি অ্যাপটি তৈরি করার জন্য আপনাকে প্রয়োজন অনুসারে অতিরিক্ত ফাইল যোগ করতে হবে।
lib/main.dart ফাইলটি পর্যালোচনা করুন
এই অ্যাপটি google_fonts প্যাকেজের সুবিধা গ্রহণ করে Roboto কে অ্যাপ জুড়ে ডিফল্ট ফন্ট হিসেবে তৈরি করে। আপনি fonts.google.com অন্বেষণ করতে পারেন এবং অ্যাপের বিভিন্ন অংশে সেখানে আবিষ্কৃত ফন্টগুলি ব্যবহার করতে পারেন।
আপনি lib/src/widgets.dart ফাইল থেকে Header , Paragraph এবং IconAndDetail আকারে সহায়ক উইজেট ব্যবহার করতে পারেন। এই উইজেটগুলি HomePage বর্ণিত পৃষ্ঠা বিন্যাসে বিশৃঙ্খলা কমাতে ডুপ্লিকেট কোড দূর করে। এটি একটি সামঞ্জস্যপূর্ণ চেহারা এবং অনুভূতিও সক্ষম করে।
অ্যান্ড্রয়েড, আইওএস, ওয়েব এবং ম্যাকওএস-এ আপনার অ্যাপটি কেমন দেখাচ্ছে তা এখানে দেওয়া হল:
|
|
|
|
৩. একটি ফায়ারবেস প্রকল্প তৈরি এবং সেট আপ করুন
ইভেন্টের তথ্য প্রদর্শন আপনার অতিথিদের জন্য দুর্দান্ত, কিন্তু এটি একা কারো জন্য খুব একটা কার্যকর নয়। আপনাকে অ্যাপটিতে কিছু গতিশীল কার্যকারিতা যোগ করতে হবে। এটি করার জন্য, আপনাকে আপনার অ্যাপের সাথে Firebase সংযোগ করতে হবে। Firebase দিয়ে শুরু করার জন্য, আপনাকে একটি Firebase প্রকল্প তৈরি এবং সেট আপ করতে হবে।
একটি ফায়ারবেস প্রকল্প তৈরি করুন
- আপনার গুগল অ্যাকাউন্ট ব্যবহার করে ফায়ারবেস কনসোলে সাইন ইন করুন।
- একটি নতুন প্রকল্প তৈরি করতে বোতামটি ক্লিক করুন, এবং তারপর একটি প্রকল্পের নাম লিখুন (উদাহরণস্বরূপ,
Firebase-Flutter-Codelab)। - চালিয়ে যান ক্লিক করুন।
- যদি অনুরোধ করা হয়, তাহলে Firebase শর্তাবলী পর্যালোচনা করুন এবং গ্রহণ করুন, এবং তারপর Continue এ ক্লিক করুন।
- (ঐচ্ছিক) Firebase কনসোলে ("Gemini in Firebase" নামে পরিচিত) AI সহায়তা সক্ষম করুন।
- এই কোডল্যাবের জন্য, আপনার গুগল অ্যানালিটিক্সের প্রয়োজন নেই , তাই গুগল অ্যানালিটিক্স বিকল্পটি টগল করে বন্ধ করে দিন ।
- Create project এ ক্লিক করুন, আপনার province করার জন্য অপেক্ষা করুন, এবং তারপর Continue এ ক্লিক করুন।
ফায়ারবেস প্রকল্প সম্পর্কে আরও জানতে, ফায়ারবেস প্রকল্পগুলি বুঝুন দেখুন।
Firebase পণ্য সেট আপ করুন
অ্যাপটি নিম্নলিখিত Firebase পণ্যগুলি ব্যবহার করে, যা ওয়েব অ্যাপের জন্য উপলব্ধ:
- প্রমাণীকরণ: ব্যবহারকারীদের আপনার অ্যাপে সাইন ইন করতে দেয়।
- ফায়ারস্টোর: ক্লাউডে স্ট্রাকচার্ড ডেটা সংরক্ষণ করে এবং ডেটা পরিবর্তন হলে তাৎক্ষণিক বিজ্ঞপ্তি পায়।
- ফায়ারবেস নিরাপত্তা নিয়ম: আপনার ডাটাবেস সুরক্ষিত করে।
এই পণ্যগুলির মধ্যে কিছুর বিশেষ কনফিগারেশন প্রয়োজন অথবা আপনাকে Firebase কনসোলে সেগুলি সক্ষম করতে হবে।
ইমেল সাইন-ইন প্রমাণীকরণ সক্ষম করুন
- ফায়ারবেস কনসোলের প্রজেক্ট ওভারভিউ প্যানে, বিল্ড মেনুটি প্রসারিত করুন।
- প্রমাণীকরণ > শুরু করুন > সাইন-ইন পদ্ধতি > ইমেল/পাসওয়ার্ড > সক্ষম করুন > সংরক্ষণ করুন এ ক্লিক করুন।

ফায়ারস্টোর সেট আপ করুন
ওয়েব অ্যাপটি চ্যাট বার্তা সংরক্ষণ এবং নতুন চ্যাট বার্তা গ্রহণের জন্য ফায়ারস্টোর ব্যবহার করে।
আপনার Firebase প্রকল্পে Firestore কীভাবে সেট আপ করবেন তা এখানে দেওয়া হল:
- Firebase কনসোলের বাম প্যানেলে, Build প্রসারিত করুন এবং তারপর Firestore database নির্বাচন করুন।
- ডাটাবেস তৈরি করুন ক্লিক করুন।
- স্ট্যান্ডার্ড সংস্করণ নির্বাচন করুন এবং পরবর্তী ক্লিক করুন।
- ডাটাবেস আইডি
(default)এ সেট করে রাখুন। - আপনার ডাটাবেসের জন্য একটি অবস্থান নির্বাচন করুন, তারপর পরবর্তী ক্লিক করুন।
একটি আসল অ্যাপের জন্য, আপনাকে এমন একটি অবস্থান বেছে নিতে হবে যা আপনার ব্যবহারকারীদের কাছাকাছি। - পরীক্ষা মোডে শুরু করুন ক্লিক করুন। নিরাপত্তা নিয়ম সম্পর্কে দাবিত্যাগ পড়ুন।
এই কোডল্যাবে পরে, আপনার ডেটা সুরক্ষিত করার জন্য আপনি সুরক্ষা নিয়ম যোগ করবেন। আপনার ডাটাবেসের জন্য সুরক্ষা নিয়ম যোগ না করে কোনও অ্যাপ সর্বজনীনভাবে বিতরণ বা প্রকাশ করবেন না । - তৈরি করুন ক্লিক করুন।
৪. ফায়ারবেস কনফিগার করুন
Flutter এর সাথে Firebase ব্যবহার করার জন্য, FlutterFire লাইব্রেরিগুলি সঠিকভাবে ব্যবহার করার জন্য Flutter প্রকল্পটি কনফিগার করার জন্য আপনাকে নিম্নলিখিত কাজগুলি সম্পন্ন করতে হবে:
- আপনার প্রকল্পে
FlutterFireনির্ভরতা যোগ করুন। - Firebase প্রকল্পে নির্বাচিত প্ল্যাটফর্মটি নিবন্ধন করুন।
- প্ল্যাটফর্ম-নির্দিষ্ট কনফিগারেশন ফাইলটি ডাউনলোড করুন এবং তারপর কোডে এটি যোগ করুন।
আপনার Flutter অ্যাপের শীর্ষ-স্তরের ডিরেক্টরিতে, android , ios , macos এবং web সাবডিরেক্টরি রয়েছে, যা যথাক্রমে iOS এবং Android এর জন্য প্ল্যাটফর্ম-নির্দিষ্ট কনফিগারেশন ফাইল ধারণ করে।
নির্ভরতা কনফিগার করুন
এই অ্যাপে আপনি যে দুটি ফায়ারবেস পণ্য ব্যবহার করেন তার জন্য আপনাকে FlutterFire লাইব্রেরি যোগ করতে হবে: প্রমাণীকরণ এবং ফায়ারস্টোর।
- কমান্ড লাইন থেকে, আপনার অ্যাপের রুট থেকে নিম্নলিখিত নির্ভরতাগুলি যোগ করুন (
.../firebase-get-to-know-flutter/step_02):
$ flutter pub add firebase_core firebase_auth cloud_firestore provider firebase_ui_auth
আপনার Flutter অ্যাপে Firebase ব্যবহার করতে, আপনাকে কয়েকটি বিশেষায়িত প্যাকেজ একত্রিত করতে হবে:
-
firebase_coreপ্যাকেজ : এটি হল অপরিহার্য সূচনা বিন্দু। আপনার অবশ্যই এই প্যাকেজটি থাকা উচিত, কারণ Flutter-এর জন্য অন্যান্য সমস্ত Firebase টুল এর উপর নির্ভর করে। -
firebase_authপ্যাকেজ : এই প্যাকেজটি ব্যবহারকারীর অ্যাকাউন্ট পরিচালনার জন্য। এটি আপনাকে সাইন-আপ, লগইন এবং লগআউটের মতো বৈশিষ্ট্য যোগ করতে দেয়। -
cloud_firestoreপ্যাকেজ : আপনার অ্যাপটিকে Firestore ডাটাবেসের সাথে সংযুক্ত করতে এটি ব্যবহার করুন, যার ফলে আপনি আপনার অ্যাপের ডেটা সংরক্ষণ এবং অ্যাক্সেস করতে পারবেন। -
firebase_ui_authপ্যাকেজ : এই প্যাকেজটি প্রমাণীকরণ সেট আপ করা অনেক দ্রুত করে। এটি ব্যবহারের জন্য প্রস্তুত উইজেট (যেমন পূর্বনির্ধারিত লগইন স্ক্রিন) প্রদান করে, তাই আপনাকে সবকিছু শুরু থেকে তৈরি করতে হবে না। -
providerপ্যাকেজ : এটি রাজ্য ব্যবস্থাপনার জন্য একটি জনপ্রিয় পছন্দ। এটি আপনার অ্যাপকে তথ্যের ট্র্যাক রাখতে সাহায্য করে (যেমন কে লগ ইন করেছে) এবং সেই ডেটা বিভিন্ন স্ক্রিনে উপলব্ধ করে যেখানে এটির প্রয়োজন।
আপনি প্রয়োজনীয় প্যাকেজ যোগ করেছেন, কিন্তু Firebase সঠিকভাবে ব্যবহার করার জন্য আপনাকে iOS, Android, macOS এবং Web রানার প্রজেক্টগুলিও কনফিগার করতে হবে। আপনি provider প্যাকেজও ব্যবহার করেন যা ডিসপ্লে লজিক থেকে ব্যবসায়িক লজিককে পৃথক করতে সক্ষম করে।
FlutterFire CLI ইনস্টল করুন
FlutterFire CLI অন্তর্নিহিত Firebase CLI এর উপর নির্ভর করে।
- যদি আপনি ইতিমধ্যেই এটি না করে থাকেন, তাহলে আপনার মেশিনে Firebase CLI ইনস্টল করুন।
- FlutterFire CLI ইনস্টল করুন:
$ dart pub global activate flutterfire_cli
একবার ইনস্টল হয়ে গেলে, flutterfire কমান্ডটি বিশ্বব্যাপী উপলব্ধ।
আপনার অ্যাপগুলি কনফিগার করুন
CLI আপনার Firebase প্রকল্প এবং নির্বাচিত প্রকল্প অ্যাপগুলি থেকে তথ্য সংগ্রহ করে একটি নির্দিষ্ট প্ল্যাটফর্মের জন্য সমস্ত কনফিগারেশন তৈরি করে।
আপনার অ্যাপের রুটে ( flutter-codelabs/firebase-get-to-know-flutter/step_02 ), configure কমান্ডটি চালান:
$ flutterfire configure
কনফিগারেশন কমান্ড নিম্নলিখিত প্রক্রিয়াগুলি সম্পাদন করে:
-
.firebasercফাইলের উপর ভিত্তি করে অথবা Firebase কনসোল থেকে একটি Firebase প্রকল্প নির্বাচন করুন। - অ্যান্ড্রয়েড, আইওএস, ম্যাকওএস এবং ওয়েবের মতো কনফিগারেশনের জন্য প্ল্যাটফর্ম নির্ধারণ করুন।
- কোন Firebase অ্যাপগুলি থেকে কনফিগারেশন বের করতে হবে তা শনাক্ত করুন। ডিফল্টরূপে, CLI আপনার বর্তমান প্রোজেক্ট কনফিগারেশনের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে Firebase অ্যাপগুলির সাথে মিল করার চেষ্টা করে।
- আপনার প্রকল্পে একটি
firebase_options.dartফাইল তৈরি করুন।
ম্যাকোস কনফিগার করুন
MacOS-এ Flutter সম্পূর্ণরূপে স্যান্ডবক্সযুক্ত অ্যাপ তৈরি করে। যেহেতু এই অ্যাপটি Firebase সার্ভারের সাথে যোগাযোগ করার জন্য নেটওয়ার্কের সাথে একীভূত হয়, তাই আপনাকে নেটওয়ার্ক ক্লায়েন্ট সুবিধা সহ আপনার অ্যাপটি কনফিগার করতে হবে।
ম্যাকোস/রানার/ডিবাগপ্রোফাইল.এনটাইটেলমেন্টস
<?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>
আরও তথ্যের জন্য, Flutter এর জন্য ডেস্কটপ সমর্থন দেখুন।
৫. RSVP কার্যকারিতা যোগ করুন
এখন যেহেতু আপনি অ্যাপটিতে Firebase যোগ করেছেন, আপনি একটি RSVP বোতাম তৈরি করতে পারেন যা প্রমাণীকরণের মাধ্যমে লোকেদের নিবন্ধন করে। অ্যান্ড্রয়েড নেটিভ, iOS নেটিভ এবং ওয়েবের জন্য, পূর্বে তৈরি FirebaseUI Auth প্যাকেজ রয়েছে, তবে Flutter এর জন্য আপনাকে এই ক্ষমতা তৈরি করতে হবে।
আপনি আগে যে প্রকল্পটি পুনরুদ্ধার করেছিলেন তাতে উইজেটের একটি সেট অন্তর্ভুক্ত ছিল যা বেশিরভাগ প্রমাণীকরণ প্রবাহের জন্য ব্যবহারকারী ইন্টারফেস প্রয়োগ করে। আপনি অ্যাপের সাথে প্রমাণীকরণ সংহত করার জন্য ব্যবসায়িক যুক্তি প্রয়োগ করেন।
Provider প্যাকেজের সাথে ব্যবসায়িক যুক্তি যোগ করুন
অ্যাপের ফ্লাটার উইজেট ট্রি জুড়ে একটি কেন্দ্রীভূত অ্যাপ স্টেট অবজেক্ট উপলব্ধ করতে provider প্যাকেজটি ব্যবহার করুন:
- নিম্নলিখিত কন্টেন্ট সহ
app_state.dartনামে একটি নতুন ফাইল তৈরি করুন:
lib/app_state.dart
import 'package:firebase_auth/firebase_auth.dart'
hide EmailAuthProvider, PhoneAuthProvider;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';
class ApplicationState extends ChangeNotifier {
ApplicationState() {
init();
}
bool _loggedIn = false;
bool get loggedIn => _loggedIn;
Future<void> init() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform);
FirebaseUIAuth.configureProviders([
EmailAuthProvider(),
]);
FirebaseAuth.instance.userChanges().listen((user) {
if (user != null) {
_loggedIn = true;
} else {
_loggedIn = false;
}
notifyListeners();
});
}
}
import স্টেটমেন্টগুলি Firebase Core এবং Auth-এর সাথে পরিচয় করিয়ে দেয়, provider প্যাকেজটি টেনে আনে যা উইজেট ট্রি জুড়ে অ্যাপ স্টেট অবজেক্ট উপলব্ধ করে এবং firebase_ui_auth প্যাকেজ থেকে প্রমাণীকরণ উইজেটগুলি অন্তর্ভুক্ত করে।
এই ধাপের জন্য এই ApplicationState অ্যাপ্লিকেশন স্টেট ক্লাসের একটি প্রধান দায়িত্ব রয়েছে, যা হল উইজেট ট্রিকে সতর্ক করা যে একটি প্রমাণিত অবস্থায় আপডেট করা হয়েছে।
আপনি শুধুমাত্র একটি প্রদানকারী ব্যবহার করে অ্যাপে ব্যবহারকারীর লগইন স্ট্যাটাসের অবস্থা জানাতে পারেন। ব্যবহারকারীকে সাইন ইন করতে দেওয়ার জন্য, আপনি firebase_ui_auth প্যাকেজ দ্বারা প্রদত্ত UI ব্যবহার করেন, যা আপনার অ্যাপগুলিতে দ্রুত লগইন স্ক্রিন বুটস্ট্র্যাপ করার একটি দুর্দান্ত উপায়।
প্রমাণীকরণ প্রবাহকে একীভূত করুন
-
lib/main.dartফাইলের উপরে আমদানিগুলি পরিবর্তন করুন:
lib/main.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart'; // new
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; // new
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart'; // new
import 'app_state.dart'; // new
import 'home_page.dart';
- অ্যাপের অবস্থা অ্যাপ ইনিশিয়ালাইজেশনের সাথে সংযুক্ত করুন এবং তারপর
HomePageএ প্রমাণীকরণ প্রবাহ যোগ করুন:
lib/main.dart
void main() {
// Modify from here...
WidgetsFlutterBinding.ensureInitialized();
runApp(ChangeNotifierProvider(
create: (context) => ApplicationState(),
builder: ((context, child) => const App()),
));
// ...to here.
}
main() ফাংশনের পরিবর্তনের ফলে প্রোভাইডার প্যাকেজটি অ্যাপ স্টেট অবজেক্টকে ChangeNotifierProvider উইজেটের সাথে ইন্সট্যান্সিয়েশনের জন্য দায়ী হয়। আপনি এই নির্দিষ্ট provider ক্লাসটি ব্যবহার করেন কারণ অ্যাপ স্টেট অবজেক্ট ChangeNotifier ক্লাসকে প্রসারিত করে, যা provider প্যাকেজকে কখন নির্ভরশীল উইজেটগুলি পুনরায় প্রদর্শন করতে হবে তা জানতে দেয়।
-
GoRouterকনফিগারেশন তৈরি করেFirebaseUIআপনার জন্য যে বিভিন্ন স্ক্রিন সরবরাহ করে তাতে নেভিগেশন পরিচালনা করতে আপনার অ্যাপটি আপডেট করুন:
lib/main.dart
// Add GoRouter configuration outside the App class
final _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => const HomePage(),
routes: [
GoRoute(
path: 'sign-in',
builder: (context, state) {
return SignInScreen(
actions: [
ForgotPasswordAction(((context, email) {
final uri = Uri(
path: '/sign-in/forgot-password',
queryParameters: <String, String?>{
'email': email,
},
);
context.push(uri.toString());
})),
AuthStateChangeAction(((context, state) {
final user = switch (state) {
SignedIn state => state.user,
UserCreated state => state.credential.user,
_ => null
};
if (user == null) {
return;
}
if (state is UserCreated) {
user.updateDisplayName(user.email!.split('@')[0]);
}
if (!user.emailVerified) {
user.sendEmailVerification();
const snackBar = SnackBar(
content: Text(
'Please check your email to verify your email address'));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
context.pushReplacement('/');
})),
],
);
},
routes: [
GoRoute(
path: 'forgot-password',
builder: (context, state) {
final arguments = state.uri.queryParameters;
return ForgotPasswordScreen(
email: arguments['email'],
headerMaxExtent: 200,
);
},
),
],
),
GoRoute(
path: 'profile',
builder: (context, state) {
return ProfileScreen(
providers: const [],
actions: [
SignedOutAction((context) {
context.pushReplacement('/');
}),
],
);
},
),
],
),
],
);
// end of GoRouter configuration
// Change MaterialApp to MaterialApp.router and add the routerConfig
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Firebase Meetup',
theme: ThemeData(
buttonTheme: Theme.of(context).buttonTheme.copyWith(
highlightColor: Colors.deepPurple,
),
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
textTheme: GoogleFonts.robotoTextTheme(
Theme.of(context).textTheme,
),
visualDensity: VisualDensity.adaptivePlatformDensity
),
routerConfig: _router, // new
);
}
}
প্রমাণীকরণ প্রবাহের নতুন অবস্থার উপর ভিত্তি করে প্রতিটি স্ক্রিনের সাথে আলাদা ধরণের ক্রিয়া যুক্ত থাকে। প্রমাণীকরণের বেশিরভাগ অবস্থা পরিবর্তনের পরে, আপনি পছন্দের স্ক্রিনে ফিরে যেতে পারেন, তা সে হোম স্ক্রিন হোক বা প্রোফাইলের মতো অন্য স্ক্রিন।
-
HomePageক্লাসের বিল্ড পদ্ধতিতে,AuthFuncউইজেটের সাথে অ্যাপ স্টেট ইন্টিগ্রেট করুন:
lib/home_page.dart
import 'package:firebase_auth/firebase_auth.dart' // new
hide EmailAuthProvider, PhoneAuthProvider; // new
import 'package:flutter/material.dart'; // new
import 'package:provider/provider.dart'; // new
import 'app_state.dart'; // new
import 'src/authentication.dart'; // new
import 'src/widgets.dart';
class HomePage extends StatelessWidget {
const HomePage({super.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, _) => AuthFunc(
loggedIn: appState.loggedIn,
signOut: () {
FirebaseAuth.instance.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!',
),
],
),
);
}
}
আপনি AuthFunc উইজেটটি ইন্সট্যান্টিয়েট করে একটি Consumer উইজেটে মুড়ে ফেলবেন। অ্যাপের অবস্থা পরিবর্তন হলে provider প্যাকেজটি গাছের কিছু অংশ পুনর্নির্মাণের জন্য কনজিউমার উইজেট ব্যবহার করার স্বাভাবিক উপায়। AuthFunc উইজেট হল পরিপূরক উইজেট যা আপনি পরীক্ষা করেন।
প্রমাণীকরণ প্রবাহ পরীক্ষা করতে অ্যাপটি চালান

- অ্যাপে,
SignInScreenশুরু করতে RSVP বোতামে ট্যাপ করুন।

- একটি ইমেল ঠিকানা লিখুন। যদি আপনি ইতিমধ্যেই নিবন্ধিত থাকেন, তাহলে সিস্টেম আপনাকে একটি পাসওয়ার্ড লিখতে বলবে। অন্যথায়, সিস্টেম আপনাকে নিবন্ধন ফর্মটি পূরণ করতে বলবে।

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

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

ফায়ারস্টোরে বার্তা যোগ করুন
এই বিভাগে, আপনি ব্যবহারকারীদের ডাটাবেসে বার্তা লেখার কার্যকারিতা যোগ করবেন। প্রথমে, আপনি একটি ফর্ম ক্ষেত্র এবং প্রেরণ বোতাম যোগ করবেন, এবং তারপর আপনি কোড যোগ করবেন যা এই উপাদানগুলিকে ডাটাবেসের সাথে সংযুক্ত করবে।
-
guest_book.dartনামে একটি নতুন ফাইল তৈরি করুন, একটি বার্তা ক্ষেত্রের UI উপাদান এবং একটি প্রেরণ বোতাম তৈরি করতে একটিGuestBookstateful উইজেট যুক্ত করুন:
lib/guest_book.dart সম্পর্কে
import 'dart:async';
import 'package:flutter/material.dart';
import 'src/widgets.dart';
class GuestBook extends StatefulWidget {
const GuestBook({required this.addMessage, super.key});
final FutureOr<void> Function(String message) addMessage;
@override
State<GuestBook> 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'),
],
),
),
],
),
),
);
}
}
এখানে কয়েকটি বিষয়ের গুরুত্ব রয়েছে। প্রথমে, আপনি একটি ফর্ম ইন্সট্যান্টিয়েট করুন যাতে আপনি যাচাই করতে পারেন যে বার্তাটিতে আসলেই কন্টেন্ট আছে এবং যদি কোনও ত্রুটি বার্তা না থাকে তবে ব্যবহারকারীকে একটি ত্রুটি বার্তা দেখান। একটি ফর্ম যাচাই করতে, আপনাকে GlobalKey ব্যবহার করে ফর্মের পিছনের ফর্ম স্টেট অ্যাক্সেস করতে হবে। কী এবং কীভাবে সেগুলি ব্যবহার করবেন সে সম্পর্কে আরও তথ্যের জন্য, কী কখন ব্যবহার করবেন দেখুন।
উইজেটগুলি কীভাবে সাজানো হয়েছে তাও লক্ষ্য করুন, আপনার কাছে একটি TextFormField সহ একটি Row এবং একটি StyledButton আছে, যার মধ্যে একটি Row রয়েছে। এছাড়াও লক্ষ্য করুন যে TextFormField একটি Expanded উইজেটে মোড়ানো আছে, যা TextFormField সারিতে যেকোনো অতিরিক্ত স্থান পূরণ করতে বাধ্য করে। কেন এটি প্রয়োজন তা আরও ভালভাবে বুঝতে, Understanding constraints দেখুন।
এখন যেহেতু আপনার কাছে একটি উইজেট আছে যা ব্যবহারকারীকে গেস্ট বুকে যোগ করার জন্য কিছু টেক্সট লিখতে সক্ষম করে, আপনাকে এটি স্ক্রিনে আনতে হবে।
-
ListViewএর শিশুদের শেষে নিম্নলিখিত দুটি লাইন যোগ করার জন্যHomePageএর মূল অংশ সম্পাদনা করুন:
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)),
যদিও এটি উইজেটটি প্রদর্শনের জন্য যথেষ্ট, তবে এটি কোনও কার্যকরী কাজের জন্য যথেষ্ট নয়। আপনি এই কোডটি শীঘ্রই আপডেট করুন যাতে এটি কার্যকরী হয়।
অ্যাপ প্রিভিউ
|
|
|
|
যখন একজন ব্যবহারকারী SEND এ ক্লিক করেন, তখন এটি নিম্নলিখিত কোড স্নিপেটটি ট্রিগার করে। এটি ডাটাবেসের guestbook সংগ্রহে বার্তা ইনপুট ক্ষেত্রের বিষয়বস্তু যোগ করে। বিশেষ করে, addMessageToGuestBook পদ্ধতিটি guestbook সংগ্রহে স্বয়ংক্রিয়ভাবে তৈরি আইডি সহ একটি নতুন নথিতে বার্তার বিষয়বস্তু যোগ করে।
মনে রাখবেন যে FirebaseAuth.instance.currentUser.uid হল স্বয়ংক্রিয়ভাবে তৈরি হওয়া অনন্য আইডির একটি রেফারেন্স যা প্রমাণীকরণ সমস্ত লগ-ইন করা ব্যবহারকারীদের জন্য দেয়।
-
lib/app_state.dartফাইলে,addMessageToGuestBookপদ্ধতিটি যোগ করুন। আপনি পরবর্তী ধাপে এই ক্ষমতাটি ইউজার ইন্টারফেসের সাথে সংযুক্ত করবেন।
lib/app_state.dart
import 'package:cloud_firestore/cloud_firestore.dart'; // new
import 'package:firebase_auth/firebase_auth.dart'
hide EmailAuthProvider, PhoneAuthProvider;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';
class ApplicationState extends ChangeNotifier {
// Current content of ApplicationState elided ...
// Add from here...
Future<DocumentReference> addMessageToGuestBook(String message) {
if (!_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 আছে যেখানে ব্যবহারকারী গেস্ট বুকে যে টেক্সট যোগ করতে চান তা লিখতে পারেন এবং আপনার কাছে Firestore-এ এন্ট্রি যোগ করার কোড আছে। এখন আপনাকে যা করতে হবে তা হল দুটিকে সংযুক্ত করা।
-
lib/home_page.dartফাইলে,HomePageউইজেটে নিম্নলিখিত পরিবর্তনগুলি করুন:
lib/home_page.dart
import 'package:firebase_auth/firebase_auth.dart'
hide EmailAuthProvider, PhoneAuthProvider;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'app_state.dart';
import 'guest_book.dart'; // new
import 'src/authentication.dart';
import 'src/widgets.dart';
class HomePage extends StatelessWidget {
const HomePage({super.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, _) => AuthFunc(
loggedIn: appState.loggedIn,
signOut: () {
FirebaseAuth.instance.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.loggedIn) ...[
const Header('Discussion'),
GuestBook(
addMessage: (message) =>
appState.addMessageToGuestBook(message),
),
],
],
),
),
// ...to here.
],
),
);
}
}
এই ধাপের শুরুতে আপনি যে দুটি লাইন যোগ করেছিলেন তা সম্পূর্ণ বাস্তবায়নের মাধ্যমে প্রতিস্থাপন করেছেন। আপনি আবার Consumer<ApplicationState> ব্যবহার করে অ্যাপ স্টেটটি আপনার রেন্ডার করা ট্রির অংশে উপলব্ধ করেন। এটি আপনাকে এমন কাউকে প্রতিক্রিয়া জানাতে দেয় যিনি UI-তে একটি বার্তা প্রবেশ করান এবং এটি ডাটাবেসে প্রকাশ করেন। পরবর্তী বিভাগে, আপনি পরীক্ষা করবেন যে যোগ করা বার্তাগুলি ডাটাবেসে প্রকাশিত হয়েছে কিনা।
বার্তা পাঠানোর পরীক্ষা করুন
- প্রয়োজনে অ্যাপে সাইন ইন করুন।
- একটি বার্তা লিখুন, যেমন
Hey there!, এবং তারপর SEND এ ক্লিক করুন।
এই ক্রিয়াটি আপনার ফায়ারস্টোর ডাটাবেসে বার্তাটি লিখে। তবে, আপনি আপনার প্রকৃত ফ্লটার অ্যাপে বার্তাটি দেখতে পাবেন না কারণ আপনাকে এখনও ডেটা পুনরুদ্ধার বাস্তবায়ন করতে হবে, যা আপনি পরবর্তী ধাপে করবেন। তবে, ফায়ারবেস কনসোল ডেটাবেস ড্যাশবোর্ডে , আপনি guestbook সংগ্রহে আপনার যুক্ত বার্তাটি দেখতে পাবেন। আপনি যদি আরও বার্তা পাঠান, তাহলে আপনি আপনার guestbook সংগ্রহে আরও নথি যুক্ত করবেন। উদাহরণস্বরূপ, নিম্নলিখিত কোড স্নিপেটটি দেখুন:

৭. বার্তা পড়ুন
এটা খুবই ভালো যে অতিথিরা ডাটাবেসে বার্তা লিখতে পারেন, কিন্তু তারা এখনও অ্যাপে সেগুলি দেখতে পাচ্ছেন না। এটি ঠিক করার সময় এসেছে!
বার্তাগুলি সিঙ্ক্রোনাইজ করুন
বার্তা প্রদর্শনের জন্য, আপনাকে এমন শ্রোতা যুক্ত করতে হবে যা ডেটা পরিবর্তনের সময় ট্রিগার করে এবং তারপর একটি UI উপাদান তৈরি করতে হবে যা নতুন বার্তা দেখায়। আপনি অ্যাপ স্টেটে কোড যুক্ত করবেন যা অ্যাপ থেকে নতুন যোগ করা বার্তাগুলি শোনে।
- একটি নতুন ফাইল তৈরি করুন
guest_book_message.dart, ফায়ারস্টোরে আপনার সংরক্ষণ করা ডেটার একটি কাঠামোগত দৃশ্য প্রকাশ করতে নিম্নলিখিত ক্লাসটি যুক্ত করুন।
lib/guest_book_message.dart সম্পর্কে
class GuestBookMessage {
GuestBookMessage({required this.name, required this.message});
final String name;
final String message;
}
-
lib/app_state.dartফাইলে, নিম্নলিখিত আমদানিগুলি যোগ করুন:
lib/app_state.dart
import 'dart:async'; // new
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart'
hide EmailAuthProvider, PhoneAuthProvider;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';
import 'guest_book_message.dart'; // new
-
ApplicationStateএর অংশে যেখানে আপনি state এবং getters সংজ্ঞায়িত করেন, সেখানে নিম্নলিখিত লাইনগুলি যোগ করুন:
lib/app_state.dart
bool _loggedIn = false;
bool get loggedIn => _loggedIn;
// Add from here...
StreamSubscription<QuerySnapshot>? _guestBookSubscription;
List<GuestBookMessage> _guestBookMessages = [];
List<GuestBookMessage> get guestBookMessages => _guestBookMessages;
// ...to here.
-
ApplicationStateএর ইনিশিয়ালাইজেশন বিভাগে, ব্যবহারকারী লগ ইন করলে ডকুমেন্ট সংগ্রহের উপর একটি কোয়েরিতে সাবস্ক্রাইব করতে এবং লগ আউট করলে আনসাবস্ক্রাইব করতে নিম্নলিখিত লাইনগুলি যোগ করুন:
lib/app_state.dart
Future<void> init() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform);
FirebaseUIAuth.configureProviders([
EmailAuthProvider(),
]);
FirebaseAuth.instance.userChanges().listen((user) {
if (user != null) {
_loggedIn = true;
// 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 {
_loggedIn = false;
// Add from here...
_guestBookMessages = [];
_guestBookSubscription?.cancel();
// to here.
}
notifyListeners();
});
}
এই বিভাগটি গুরুত্বপূর্ণ কারণ এখানেই আপনি guestbook সংগ্রহের উপর একটি প্রশ্ন তৈরি করেন এবং এই সংগ্রহে সাবস্ক্রাইব এবং আনসাবস্ক্রাইবিং পরিচালনা করেন। আপনি স্ট্রিমটি শোনেন, যেখানে আপনি guestbook সংগ্রহের বার্তাগুলির একটি স্থানীয় ক্যাশে পুনর্গঠন করেন এবং এই সাবস্ক্রিপশনের একটি রেফারেন্সও সংরক্ষণ করেন যাতে আপনি পরে এটি থেকে আনসাবস্ক্রাইব করতে পারেন। এখানে অনেক কিছু চলছে, তাই আপনার এটি একটি ডিবাগারে অন্বেষণ করা উচিত যাতে একটি পরিষ্কার মানসিক মডেল পেতে কী ঘটে তা পরীক্ষা করা যায়। আরও তথ্যের জন্য, Firestore দিয়ে রিয়েলটাইম আপডেট পান দেখুন।
-
lib/guest_book.dartফাইলে, নিম্নলিখিত আমদানি যোগ করুন:
import 'guest_book_message.dart';
-
GuestBookউইজেটে, এই পরিবর্তনশীল অবস্থাটিকে ব্যবহারকারী ইন্টারফেসের সাথে সংযুক্ত করার জন্য কনফিগারেশনের অংশ হিসাবে বার্তাগুলির একটি তালিকা যুক্ত করুন:
lib/guest_book.dart সম্পর্কে
class GuestBook extends StatefulWidget {
// Modify the following line:
const GuestBook({
super.key,
required this.addMessage,
required this.messages,
});
final FutureOr<void> Function(String message) addMessage;
final List<GuestBookMessage> messages; // new
@override
State<GuestBook> createState() => _GuestBookState();
}
-
_GuestBookStateএ, এই কনফিগারেশনটি প্রকাশ করার জন্যbuildপদ্ধতিটি নিম্নরূপ পরিবর্তন করুন:
lib/guest_book.dart সম্পর্কে
class _GuestBookState extends State<GuestBook> {
final _formKey = GlobalKey<FormState>(debugLabel: '_GuestBookState');
final _controller = TextEditingController();
@override
Widget build(BuildContext context) {
// Modify from here...
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: [
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.
);
}
}
আপনি build() পদ্ধতির পূর্ববর্তী বিষয়বস্তু একটি Column উইজেট দিয়ে মুড়ে ফেলবেন এবং তারপর আপনি Column 's children এর লেজে একটি সংগ্রহ যোগ করবেন যাতে বার্তার তালিকার প্রতিটি বার্তার জন্য একটি নতুন Paragraph তৈরি করা যায়।
- নতুন
messagesপ্যারামিটার ব্যবহার করে সঠিকভাবেGuestBookতৈরি করতেHomePageবডি আপডেট করুন:
lib/home_page.dart
Consumer<ApplicationState>(
builder: (context, appState, _) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (appState.loggedIn) ...[
const Header('Discussion'),
GuestBook(
addMessage: (message) =>
appState.addMessageToGuestBook(message),
messages: appState.guestBookMessages, // new
),
],
],
),
),
বার্তা সিঙ্ক্রোনাইজেশন পরীক্ষা করুন
ফায়ারস্টোর স্বয়ংক্রিয়ভাবে এবং তাৎক্ষণিকভাবে ডাটাবেসে সাবস্ক্রাইব করা ক্লায়েন্টদের সাথে ডেটা সিঙ্ক্রোনাইজ করে।
বার্তা সিঙ্ক্রোনাইজেশন পরীক্ষা করুন:
- অ্যাপটিতে, ডাটাবেসে আপনার আগে তৈরি করা বার্তাগুলি খুঁজুন।
- নতুন বার্তা লিখুন। সেগুলো তাৎক্ষণিকভাবে উপস্থিত হয়।
- একাধিক উইন্ডো বা ট্যাবে আপনার কর্মক্ষেত্র খুলুন। বার্তাগুলি রিয়েল টাইমে উইন্ডো এবং ট্যাব জুড়ে সিঙ্ক হয়।
- ঐচ্ছিক: Firebase কনসোল ডেটাবেস মেনুতে, ম্যানুয়ালি বার্তাগুলি মুছুন, পরিবর্তন করুন বা নতুন বার্তা যোগ করুন। সমস্ত পরিবর্তন UI-তে প্রদর্শিত হয়।
অভিনন্দন! আপনি আপনার অ্যাপে ফায়ারস্টোর ডকুমেন্ট পড়েছেন!
অ্যাপ প্রিভিউ
|
|
|
|
৮. মৌলিক নিরাপত্তা নিয়ম সেট আপ করুন
আপনি প্রথমে Firestore সেট আপ করেন টেস্ট মোড ব্যবহার করার জন্য, যার অর্থ হল আপনার ডাটাবেসটি পঠন এবং লেখার জন্য উন্মুক্ত। তবে, আপনার শুধুমাত্র ডেভেলপমেন্টের প্রাথমিক পর্যায়ে টেস্ট মোড ব্যবহার করা উচিত। সর্বোত্তম অনুশীলন হিসাবে, আপনার অ্যাপ তৈরি করার সময় আপনার ডাটাবেসের জন্য সুরক্ষা নিয়ম সেট আপ করা উচিত। নিরাপত্তা আপনার অ্যাপের গঠন এবং আচরণের অবিচ্ছেদ্য অংশ।
ফায়ারবেস সিকিউরিটি রুলস আপনাকে আপনার ডাটাবেসে ডকুমেন্ট এবং সংগ্রহের অ্যাক্সেস নিয়ন্ত্রণ করতে দেয়। নমনীয় রুলস সিনট্যাক্স আপনাকে এমন নিয়ম তৈরি করতে দেয় যা সমস্ত লেখা থেকে শুরু করে পুরো ডাটাবেসের সাথে একটি নির্দিষ্ট ডকুমেন্টের ক্রিয়াকলাপের সাথে মেলে।
মৌলিক নিরাপত্তা নিয়ম সেট আপ করুন:
- Firebase কনসোলের Develop মেনুতে, Database > Rules এ ক্লিক করুন। আপনি নিম্নলিখিত ডিফল্ট নিরাপত্তা নিয়ম এবং নিয়মগুলি সর্বজনীন হওয়ার বিষয়ে একটি সতর্কতা দেখতে পাবেন:

- অ্যাপটি কোন সংগ্রহগুলিতে ডেটা লেখে তা চিহ্নিত করুন:
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;
}
}
}
৯. বোনাস ধাপ: আপনি যা শিখেছেন তা অনুশীলন করুন
একজন অংশগ্রহণকারীর RSVP স্ট্যাটাস রেকর্ড করুন
এই মুহূর্তে, আপনার অ্যাপটি শুধুমাত্র তখনই চ্যাট করতে দেয় যখন তারা ইভেন্টে আগ্রহী হয়। এছাড়াও, কেউ আসছে কিনা তা জানার একমাত্র উপায় হল চ্যাটে যখন তারা তা বলে।
এই ধাপে, আপনি সংগঠিত হন এবং লোকেদের জানান যে কতজন আসছে। আপনি অ্যাপ স্টেটে কয়েকটি ক্ষমতা যোগ করেন। প্রথমটি হল লগ-ইন করা ব্যবহারকারীর জন্য তারা উপস্থিত হচ্ছে কিনা তা মনোনীত করার ক্ষমতা। দ্বিতীয়টি হল কতজন উপস্থিত হচ্ছে তার একটি কাউন্টার।
-
lib/app_state.dartফাইলে,ApplicationStateএর অ্যাক্সেসর বিভাগে নিম্নলিখিত লাইনগুলি যোগ করুন যাতে UI কোড এই অবস্থার সাথে ইন্টারঅ্যাক্ট করতে পারে:
lib/app_state.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/app_state.dart
Future<void> init() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform);
FirebaseUIAuth.configureProviders([
EmailAuthProvider(),
]);
// 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) {
_loggedIn = true;
_emailVerified = user.emailVerified;
_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 {
_loggedIn = false;
_emailVerified = false;
_guestBookMessages = [];
_guestBookSubscription?.cancel();
_attendingSubscription?.cancel(); // new
}
notifyListeners();
});
}
এই কোডটি অংশগ্রহণকারীদের সংখ্যা নির্ধারণের জন্য একটি সর্বদা-সাবস্ক্রাইব করা কোয়েরি যোগ করে এবং দ্বিতীয় একটি কোয়েরি যা শুধুমাত্র ব্যবহারকারী লগ ইন করার সময় সক্রিয় থাকে যা ব্যবহারকারী অংশগ্রহণ করছেন কিনা তা নির্ধারণ করে।
-
lib/app_state.dartফাইলের উপরে নিম্নলিখিত গণনাটি যোগ করুন।
lib/app_state.dart
enum Attending { yes, no, unknown }
- একটি নতুন ফাইল তৈরি করুন
yes_no_selection.dart, একটি নতুন উইজেট সংজ্ঞায়িত করুন যা রেডিও বোতামের মতো কাজ করে:
lib/yes_no_selection.dart সম্পর্কে
import 'package:flutter/material.dart';
import 'app_state.dart';
import 'src/widgets.dart';
class YesNoSelection extends StatelessWidget {
const YesNoSelection(
{super.key, 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: [
FilledButton(
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),
FilledButton(
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'),
),
],
),
);
}
}
}
এটি একটি অনির্দিষ্ট অবস্থায় শুরু হয় যেখানে হ্যাঁ বা না কোনটিই নির্বাচিত হয় না। ব্যবহারকারী একবার নির্বাচন করে যে তারা উপস্থিত হচ্ছে কিনা, আপনি একটি পূর্ণ বোতাম দিয়ে হাইলাইট করা বিকল্পটি দেখান এবং অন্য বিকল্পটি একটি সমতল রেন্ডারিংয়ের সাথে সরে যায়।
-
YesNoSelectionএর সুবিধা নিতেHomePageএরbuild()পদ্ধতি আপডেট করুন, লগ-ইন করা ব্যবহারকারীকে তারা উপস্থিত আছেন কিনা তা মনোনীত করতে সক্ষম করুন এবং ইভেন্টে অংশগ্রহণকারীদের সংখ্যা প্রদর্শন করুন:
lib/home_page.dart
import 'yes_no_selection.dart'; // new
Consumer<ApplicationState>(
builder: (context, appState, _) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Add from here...
switch (appState.attendees) {
1 => const Paragraph('1 person going'),
>= 2 => Paragraph('${appState.attendees} people going'),
_ => const Paragraph('No one going'),
},
// ...to here.
if (appState.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টি নিন এবং যাচাই করুন যে জমাদাতার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 কনসোলের Firestore ড্যাশবোর্ডে ফলাফল দেখতে বোতামগুলিতে ক্লিক করুন।
অ্যাপ প্রিভিউ
|
|
|
|
১০. অভিনন্দন!
আপনি একটি ইন্টারেক্টিভ, রিয়েল-টাইম ওয়েব অ্যাপ তৈরি করতে Firebase ব্যবহার করেছেন!















