ساخت اپلیکیشن چت با فلاتر و فایربیس بخش دوم
در بخش اول از آموزش طراحی اپلیکیشن چت در فلاتر تا مرحله ثبت نام و لاگین کردن کاربران پیش رفتیم.
در ادامه قصد داریم صفحه نمایش لیست کاربران و صفحه چت را پیاده سازی کنیم.
دریافت اطلاعات از Cloud Firestore
برای دریافت اطلاعات از پایگاه داده فایربیس استبدا باید یک آبجکت از FirebaseFirestore ایجاد کنیم.
در کد زیر آبجکت را ساختیم و نام مجموعه ای که قصد داریم اطلاعات را از آن بخوانیم هم نوشته ایم.
final FirebaseAuth _auth = FirebaseAuth.instance;
final firestoreInstance = FirebaseFirestore.instance.collection("users");
در ادامه متدی که اطلاعات را دریافت میکند با نام _userList ایجاد میکنیم که این متد از نوع Stream است به دلیل اینکه قصد داریم با تغییر اطلاعات در دیتابیس بلافاصله این تغییر در اپلیکیشن هم ایجاد شود.
Stream<QuerySnapshot> _userlist(){
return firestoreInstance.where('userid',isNotEqualTo: _auth.currentUser.uid).snapshots();
}
در این متد آبجکت ساخته شده را صدا میزنیم و از یک دستور شرطی where هم استفاده میکنیم تا لیست همه کاربران را نمایش دهد به غیر از کاربری که با آن لاگین کرده ایم.
برای بخش رابط کاربری هم از StreamBuilder به عنوان ویجت اصلی استفاده میکنیم تا تغییرات بلافاصله اعمال شود.
StreamBuilder<QuerySnapshot>(
stream:_userlist() ,
builder: (context,snapshot){
if(!snapshot.hasData){
return CircularProgressIndicator();
}
final List<Users> children = snapshot.data.docs.map((doc) =>
Users(doc['name'].toString(),doc['userid'].toString(),doc['email'].toString())
).toList();
return Container(
child: ListView.builder(
itemCount: children.length,
itemBuilder: (context,index){
return list_row(children[index]);
},
),
);
},
)
در این بخش از کد بالا هم اطلاعات دریافت شده را به لیست تبدیل میکنیم تا بتوانیم آن را نمایش دهیم.
در این قسمت از متد های fromjson در کلاس مدل استفاده نشده است.
طراحی صفحه چت
برای صفحه چت قصد داریم که طراحی زیر را انجام دهیم به همین دلیل ابتدا از بخش بالایی صفحه شروع میکنیم.
اسم بخش بالایی را header گذاشتیم و با استفاده از متد زیر که از نوع ویجت فلاتر است رابط کاربری این بخش اپلیکیشن را طراحی کردیم.
Row(
children: [
SizedBox(width:8.0),
IconButton(icon: Icon(Icons.arrow_back_ios_outlined,color: Colors.white,), onPressed: (){}),
SizedBox(width: 10.0,),
CircleAvatar(
radius: 26.0,
backgroundColor: Colors.transparent,
backgroundImage: NetworkImage('http://mrgamification.com/wp-content/uploads/2018/02/cell311_1x.png'),
),
SizedBox(width: 17.0,),
Column(
children: [
Text(widget.user.name,style: TextStyle(color: Colors.white,fontSize: 17.0,
fontWeight: FontWeight.w700),),
SizedBox(height: 3.0,),
Text('Online',style: TextStyle(color: Color(0xffc8c7d4),fontSize: 15.0),)
],
)
],
);
برای بخش ارسال پیام هم در قسمت پایین صفحه از یک ویجت Row به همراه آیکون و Textfield استفاده میکنیم.
ارسال پیام
برای ارسال پیام اطلاعات را داخل یک collection به نام messages ذخیره میکنیم.
این کالکشن دو بخش مهم دارد که مشخص میکند چه شخصی پیام را به چه شخص دیگری ارسال کرده است.
فیلد receiver مشخص میکند پیام برای کدام کاربر ارسال شده است و فیلد sender تعیین کننده فرد ارسال کننده یا در واقع صاحب پیام است.
فیلد relation برای علامت گذاری مشخصات پیام های ارسال شده بین دو کاربر است.
به دلیل اینکه این دیتابیس از نوع sql نیست و تمام پیغام های ارسال شده بین کاربران را هم ما در یک کالکشن ذخیره کردیم باید در این لیست پیام هایی که مربوط به گفتگوی دو کاربر هست را فقط پیدا کنیم.
علت انتخاب این فیلد relation به این علت است که فایربیس از عملگر or پشتیبانی نمیکند و به شکلی باید یک فیلد منحصر بفرد ایجاد میکردیم که بین هر دو کاربر مشخص شود.
void Sendmsg(var text) async{
return firebaseInstance.add({
"message":text,
"time":int.parse(_getCurrentTime()),
"sender": _auth.currentUser.uid,
"receiver":widget.user.userid,
"relation": key_relation
}).then((value) {
print("Message sent");
}).catchError((error){
print("Message failed");
});
}
برای اینکه ترتیب نمایش پیام ها مرتب باشد نیاز داریم تا تاریخ ارسال آنها را به شکل دقیق دریافت کنیم تا با هیچ پیام دیگری تداخل نداشته باشد.
String _getCurrentTime(){
var now = DateTime.now();
var date = "${now.year}${now.month.toString().padLeft(2,'0')}${now.day.toString().padLeft(2,'0')}"
"${now.hour.toString().padLeft(2,'0')}"
"${now.minute.toString().padLeft(2,'0')}${now.second.toString().padLeft(2,'0')}";
return date;
}
از طریق متد زیر لیست پیام های رد و بدل شده بین دو کاربر و دریافت میکنیم که جمله شرطی آن همان فیلد relation است.
Stream<QuerySnapshot> _chatlist(){
return firebaseInstance.where('relation',isEqualTo: key_relation)
.orderBy('time')
.snapshots();
}
برای نمایش پیام ها هم دو ویجت ایجاد میکنیم که فقط رنگ پس زمینه این دو باهم فرق دارند و پیام ارسال شده را در سمت راست و دریافت شده را در سمت چپ نمایش میدهیم.
Widget Receiver(var text){
return Align(
alignment: Alignment.topLeft,
child: Container(
padding: EdgeInsets.symmetric(vertical: 8.0,horizontal: 10.0),
margin: EdgeInsets.only(left: 10,top: 9.0),
decoration: BoxDecoration(
color: Color(0xfff1f0f5),
borderRadius: BorderRadius.circular(7.0)
),
child:Text(text,style: TextStyle(color: Color(0xff1c3865),fontSize: 18.0),)
),
);
}
برای استفاده کامل از آموزش پیشنهاد میکنم فیلم های تهیه شده را کامل مشاهده کنید.
هدف این آموزش آشنایی با فایربیس و قابلیت های اون بود نه ساخت یک اپلیکیشن واقعی چت با استفاده از فریمورک فلاتر.
امیدوارم که این آموزش براتون مفید بوده باشد.
مطالب زیر را حتما مطالعه کنید
آموزش پیاده سازی لینت Lint در برنامه نویسی فلاتر
آموزش الگوی تزریق وابستگی در فلاتر Dependency Injection
کتاب های آموزش برنامه نویسی فلاتر + دانلود PDF
آموزش نصب فلاتر و رفع خطاهای رایج ساخت پروژه + ویدیو
آموزش استفاده از نقشه در فلاتر
آموزش ساخت Navigation Drawer در فلاتر
10 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
فایربیس مگه فیلتر نیست
فیلتر نیست تحریم هست
سلام ممنون از آموزش خوبتون
ولی الان که فایربیس تحریممون کرده چیکار کنیم؟
بیشتر برای اپلیکیشن با کاربران خارجی کاربرد داره.
با سلام با اینکه تحریم هستیم راهی نیست دورش بزنیم؟؟؟
بعد بع غیر از فایربیس دیگه چه قابلیت دیگه فلاتر دارد مثل همین فایربیس باشه تا بتونیم اپلکیشین هامون رو بسازیم مثل پروژه چت و…… ممنون
میتونید یه سرور خارج از ایران داشته باشید درخواست ها توسط این سرور به فایربیس ارسال بشه یا پروکسی اگه میتونید داخل اپ بزارید.
سلام قسمت ۵ رو کی میزارید اقای رسولیان
سلام؛ ویدئوی دوم بخش دوم رو از کجا میشه دانلود کرد؟!
سلام. من اموزش ویدیویی را کامل دیدم.
ولی مسئله اینجاست که خیلی از بخش ها را متوجه نمیشم. مثلا من نمیدونم
snapshot چرا استفاده میشه و یا چرا بعضی وقتا void میسازیم بعضی وقتها widget و …
اگر بتونید اموزشی ارائه بدید که ساختار ایجاد یک فیچر رو توضیح بدید که مثلا بخوایم یه فیچر به اپمون اضاف کنیم چطوری بهترین تصمیم رو بگیریم.
ممنون
سلام
پیش نیاز این آموزش تسلط به مفاهیم پایه فلاتر میباشد. در مواردی که قصد دایم یک متد یک مقدار بازگشتی از نوع ویجت داشته باشد نوع متد را widget قرار میدهیم که بتونیم این متد و داخل متد build استفاده کنیم.