الحصول على جميع المنشورات من الfirebase مع معرفة عدد likes لكل منشور
في هذا الدرس سوف نتعرف على كيفية معرفة عدد اللايكات على المنشور وايضا سوف نقوم بعرض جميع المنشورات التي تم نشرها في التطبيق لجميع المستخدمين باستخدام فايربيز وهذا الدرس من دورة بناء تطبيق تواصل اجتماعي باستخدام الفايربيز , اذا كنت قد شاهدت الدروس السابقة فهذا الدرس لن يكون صعب عليك لان معظم الافكار تم شرحها مسبقلا ولكن في هذا الدرس سوف تستعرض معكم اكواد اكثر وطرق تفكير جديده .س
تم إنشاء هذه الدورة التدريبية بواسطة Vandad Nahavandipoor. Vlandad هو مطور iOS رائد وخبير مطور في Google. Flutter عبارة عن حزمة SDK حديثة ومجانية من Google تتيح لك تطوير تطبيقات سطح المكتب والويب والجوال باستخدام نفس الرمز. هذه دورة للمبتدئين. للبدء ، لا تحتاج حتى إلى معرفة كيفية البرمجة بأي لغة كمبيوتر. في الختام ، ستعرف كيفية نشر تطبيق iOS و Android المستند إلى Flutter على App Store و Google Play Store.
يركز الجزء الأول من الدورة على تهيئة بيئة التطوير الخاصة بك. ستتعلم كيفية إنشاء تطبيق Flutter باستخدام محرر التعليمات البرمجية المجاني Visual Studio Code. أ بعد ذلك ستتعلم كيفية صنع الشاشات وتطبيق المنطق عليها.
how to get all post from firebase
سوف نقوم بعرض جميع المنشورات بداخل صفحة الhome لذلك قمنا بعمل cubit خاص بهذه الصفحة وفي بدايته قمنا بعمل void لget posts واحضرنا من داخلها جميع المنشورات بشكل مرتب عن طريق الامر orderBy وبعدها قمنا بعمل loop على جميع العناصر والحصول على جميع اللايكات على المنشور الواحد وقمنا بملئ البيانات الموجوده بداخل class الposts وعدد اللايكات يكون عدد المستخدمين الذي نقروا على "لايك" واذا قام المستخدم الحالي بوضع لايك على المنشوار سوف نجعل القيمة الموجوده بداخل class الposts بtrue واذا لم يكن موجود نحذف اللايك وبعدها نضيف البيانات وبعدها قمنا بعمل void لوضع اللايك والاخرى لازالة اللايك من المنشور .
cubit.dart
class HomeBlocCubit extends Cubit<HomeBlocState> {
HomeBlocCubit() : super(HomeBlocInitial());
// list empty
List<Post> posts = [];
void getPosts() async {
emit(HomeLoadingPostStates());
// go to collection posts_instagram and get all date by use QuerySnapshot
await FirebaseFirestore.instance
// go to collection posts_instagram
.collection('posts_instagram')
// sort data by postId
.orderBy('postId'.split(':')[0],descending: true)
// .where('age',isGreaterThan: 18)
// get all data
.get()
// after get all data
.then((QuerySnapshot querySnapshot) async {
// empty data after every get post
posts.clear();
// loop for all user and get all data (user user)
for (var doc in querySnapshot.docs) {
// get data
Map<String, dynamic> json = doc.data() as Map<String, dynamic>;
var likes = await FirebaseFirestore.instance
.collection("posts_instagram")
.doc(json["postId"])
.collection("likes")
.get();
// set data to Post model
Post post = Post.fromJson(json);
// count of post
post.likeCount = likes.docs.length;
for (var element in likes.docs) {
if (element.data()["userId"] ==
FirebaseAuth.instance.currentUser!.uid) {
post.isLiked = true;
break;
}
else{
post.isLiked = false;
}
}
// add data .
posts.add(post);
}
print('lenghth ------------------------ ${posts.length}');
// sort data A - Z
emit(HomeSuccessPostStates());
});
}
void likePost(String postId) {
String uid = FirebaseAuth.instance.currentUser!.uid;
FirebaseFirestore.instance
.collection("posts_instagram")
.doc(postId)
.collection("likes")
.doc(uid)
.set({"userId": uid});
emit(LikePostSuccessState());
}
void unLikePost(String postId) {
String uid = FirebaseAuth.instance.currentUser!.uid;
FirebaseFirestore.instance
.collection("posts_instagram")
.doc(postId)
.collection("likes")
.doc(uid)
.delete();
emit(UnLikePostSuccessState());
}
}
How to get all post and likes
هذا الكود الخاص بالتصميم الذي سوف نعمل عليه يمكنك نسخ التصميم ولصقه لديك وهو شبيه جدا بتطبيق الانستقرام , والاجزاء الموجوده باللون الاحمر تعبر عن التغيرات التي قمنا بها في هذا الكود سوف تلاحظ ان هذه الاجزاء استخدمنا فيها الcubit والاكواد التي قمنا بها في الاعلى .
ui.dart
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late HomeBlocCubit cubit;
@override
void initState() {
super.initState();
cubit = context.read<HomeBlocCubit>();
cubit.getPosts();
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return BlocListener<HomeBlocCubit, HomeBlocState>(
listener: (context, state) {
if (state is GetStoriesDetailsSuccessState) {
onShowStoryTapped(state.storiesModel);
} else if (state is AddStorySuccessState) {
showSnackBar("Story added", context);
}
},
child: Scaffold(
backgroundColor: Colors.black,
appBar: screenAppBar(),
body: screenBody(size),
),
);
}
Widget screenBody(Size size) => ListView(
children: [
buildStories(),
const Divider(
color: Colors.white,
height: 0.1,
thickness: 0.4,
),
postsListView(size),
],
);
Widget postsListView(Size size) {
return BlocBuilder<HomeBlocCubit, HomeBlocState>(
builder: (context, state) {
return BuildCondition(
condition: cubit.posts.isNotEmpty,
builder:(context) => ListView.separated(
shrinkWrap: true,
physics: const ScrollPhysics(),
itemBuilder: (context, index) =>
buildPostItem(size, cubit.posts[index]),
separatorBuilder: (context, index) => const SizedBox(height: 8),
itemCount: cubit.posts.length),
fallback:(_)=> const LoadingPage(),
);
},
);
}
buildStories() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Row(
children: [
SizedBox(
height: 110,
child: InkWell(
onTap: () => onAddStoryTapped(),
child: Column(
children: [
Stack(
alignment: Alignment.bottomRight,
children: const [
CircleAvatar(
backgroundImage: NetworkImage(
"https://wirepicker.com/wp-content/uploads/2021/09/android-vs-ios_1200x675.jpg"),
radius: 35,
),
CircleAvatar(
backgroundColor: Colors.black,
radius: 13,
),
CircleAvatar(
backgroundColor: Colors.blue,
child: Icon(Icons.add),
radius: 11,
)
],
),
const SizedBox(
height: 5,
),
const Text(
"Your story",
style: TextStyle(color: Colors.white),
)
],
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: SizedBox(
height: 110,
child: BlocBuilder<HomeBlocCubit, HomeBlocState>(
buildWhen: (previous, current) =>
current is GetHomeStoriesSuccessState,
builder: (context, state) {
return ListView.separated(
separatorBuilder: (context, index) => const SizedBox(
width: 10,
),
itemBuilder: (context, index) => buildStoryItem(index),
itemCount: cubit.homeStories.length,
scrollDirection: Axis.horizontal,
);
},
),
),
)
],
),
);
}
buildStoryItem(int index) {
StoriesModel story = cubit.homeStories[index];
return InkWell(
onTap: () => cubit.getStoriesDetails(story.userId!),
child: Column(
children: [
Stack(
alignment: Alignment.center,
children: [
CircleAvatar(
radius: 36,
child: Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(colors: [
Color(0xff833ab4),
Color(0xfffd1d1d),
Color(0xfffcb045),
])),
),
),
CircleAvatar(
backgroundImage: NetworkImage(story.userImageUrl!),
radius: 33,
),
],
),
const SizedBox(
height: 5,
),
Text(
story.username!,
style: const TextStyle(color: Colors.white),
)
],
),
);
}
buildPostItem(Size size, Post post) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
InkWell(
onTap: () => onAddStoryTapped(),
child: Stack(
alignment: Alignment.center,
children: [
CircleAvatar(
radius: 26,
child: Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(colors: [
Color(0xff833ab4),
Color(0xfffd1d1d),
Color(0xfffcb045),
])),
),
),
CircleAvatar(
backgroundImage: NetworkImage(post.userImageUrl),
radius: 23,
),
],
),
),
const SizedBox(
width: 5,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
post.username,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 4,
),
Text(
post.locationName,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Colors.white),
),
],
),
),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.more_horiz,
color: Colors.white,
))
],
),
),
Image(
height: size.height * 0.4,
width: double.infinity,
fit: BoxFit.cover,
image: NetworkImage(post.postImageUrl)),
BlocBuilder<HomeBlocCubit, HomeBlocState>(
buildWhen: (previous, current) =>
current is LikePostSuccessState ||
current is UnLikePostSuccessState,
builder: (context, state) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Row(
children: [
IconButton(
onPressed: () {
if (post.isLiked) {
post.likeCount--;
post.isLiked = false;
cubit.unLikePost(post.postId);
} else {
post.likeCount++;
post.isLiked = true;
cubit.likePost(post.postId);
}
},
icon: Icon(
post.isLiked ? Icons.favorite : Icons.favorite_border,
color: Colors.white,
)),
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
CommentsPage(postId: post.postId),
));
},
icon: const Icon(
Icons.mode_comment_outlined,
color: Colors.white,
)),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.send_outlined,
color: Colors.white,
)),
const Spacer(),
IconButton(
onPressed: () {},
icon: const Icon(
Icons.bookmark_border,
color: Colors.white,
)),
],
),
);
},
),
BlocBuilder<HomeBlocCubit, HomeBlocState>(
buildWhen: (previous, current) =>
current is LikePostSuccessState ||
current is UnLikePostSuccessState,
builder: (context, state) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 23.0),
child: Text(
"${post.likeCount} Likes",
style: const TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
);
},
),
const SizedBox(
height: 4,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 23.0),
child: RichText(
text: TextSpan(children: [
TextSpan(
text: post.username,
style: const TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: post.postContent)
]))),
],
);
}
onAddStoryTapped() async {
final ImagePicker _picker = ImagePicker();
final List<XFile>? images = await _picker.pickMultiImage();
List<File> paths = images!.map((xFile) => File(xFile.path)).toList();
cubit.addStories(paths);
}
onShowStoryTapped(List<StoriesModel> storiesDetails) {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => StoryPage(storiesDetails: storiesDetails),
));
}
}
مزيد من المقالات