Skip to content

Commit cefeefc

Browse files
[add] like a post
1 parent b0ec244 commit cefeefc

File tree

6 files changed

+134
-34
lines changed

6 files changed

+134
-34
lines changed

.gitignore

+7-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,10 @@ app.*.symbols
4040
# Obfuscation related
4141
app.*.map.json
4242
/frontend/android/app/google-services.json
43-
/frontend/build
43+
/frontend/build
44+
/backend/functions/.eslintrc.js
45+
/backend/functions/package-lock.json
46+
/backend/.firebaserc
47+
/backend/.gitignore
48+
/backend/firebase.json
49+
/backend/functions/package.json

backend/functions/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

backend/functions/index.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const functions = require("firebase-functions");
2+
3+
const admin = require('firebase-admin');
4+
admin.initializeApp();
5+
6+
const db = admin.firestore();
7+
8+
exports.addLike = functions.firestore.document('/posts/{postId}/likes/{userId}')
9+
.onCreate((snap, context) => {
10+
return db
11+
.collection("posts")
12+
.doc(context.params.postId)
13+
.update(
14+
{
15+
likesCount: admin.firestore.FieldValue.increment(1)
16+
})
17+
})
18+
19+
exports.deleteLike = functions.firestore.document('/posts/{postId}/likes/{userId}')
20+
.onDelete((snap, context) => {
21+
return db
22+
.collection("posts")
23+
.doc(context.params.postId)
24+
.update(
25+
{
26+
likesCount: admin.firestore.FieldValue.increment(-1)
27+
})
28+
})

frontend/lib/models/post.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ class PostModel {
55
final String creator;
66
final String text;
77
final Timestamp timestamp;
8+
int likesCount;
89

9-
PostModel({this.id, this.creator, this.text, this.timestamp});
10+
PostModel(
11+
{this.id, this.creator, this.text, this.timestamp, this.likesCount});
1012
}

frontend/lib/screens/main/posts/list.dart

+59-32
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:provider/provider.dart';
33
import 'package:twitter/models/post.dart';
44
import 'package:twitter/models/user.dart';
5+
import 'package:twitter/services/posts.dart';
56
import 'package:twitter/services/user.dart';
67

78
class ListPosts extends StatefulWidget {
@@ -13,6 +14,7 @@ class ListPosts extends StatefulWidget {
1314

1415
class _ListPostsState extends State<ListPosts> {
1516
UserService _userService = UserService();
17+
PostService _postService = PostService();
1618
@override
1719
Widget build(BuildContext context) {
1820
final posts = Provider.of<List<PostModel>>(context) ?? [];
@@ -23,44 +25,69 @@ class _ListPostsState extends State<ListPosts> {
2325
final post = posts[index];
2426
return StreamBuilder(
2527
stream: _userService.getUserInfo(post.creator),
26-
builder: (BuildContext context, AsyncSnapshot<UserModel> snapshot) {
27-
if (!snapshot.hasData) {
28+
builder:
29+
(BuildContext context, AsyncSnapshot<UserModel> snapshotUser) {
30+
if (!snapshotUser.hasData) {
2831
return Center(child: CircularProgressIndicator());
2932
}
30-
return ListTile(
31-
title: Padding(
32-
padding: EdgeInsets.fromLTRB(0, 15, 0, 15),
33-
child: Row(
34-
children: [
35-
snapshot.data.profileImageUrl != ''
36-
? CircleAvatar(
37-
radius: 20,
38-
backgroundImage:
39-
NetworkImage(snapshot.data.profileImageUrl))
40-
: Icon(Icons.person, size: 40),
41-
SizedBox(width: 10),
42-
Text(snapshot.data.name)
43-
],
44-
),
45-
),
46-
subtitle: Column(
47-
crossAxisAlignment: CrossAxisAlignment.start,
48-
children: [
49-
Padding(
50-
padding: EdgeInsets.fromLTRB(0, 15, 0, 15),
51-
child: Column(
33+
34+
//stream builder to get user like
35+
return StreamBuilder(
36+
stream: _postService.getCurrentUserLike(post),
37+
builder:
38+
(BuildContext context, AsyncSnapshot<bool> snapshotLike) {
39+
if (!snapshotLike.hasData) {
40+
return Center(child: CircularProgressIndicator());
41+
}
42+
43+
return ListTile(
44+
title: Padding(
45+
padding: EdgeInsets.fromLTRB(0, 15, 0, 15),
46+
child: Row(
47+
children: [
48+
snapshotUser.data.profileImageUrl != ''
49+
? CircleAvatar(
50+
radius: 20,
51+
backgroundImage: NetworkImage(
52+
snapshotUser.data.profileImageUrl))
53+
: Icon(Icons.person, size: 40),
54+
SizedBox(width: 10),
55+
Text(snapshotUser.data.name)
56+
],
57+
),
58+
),
59+
subtitle: Column(
5260
crossAxisAlignment: CrossAxisAlignment.start,
5361
children: [
54-
Text(post.text),
55-
SizedBox(height: 20),
56-
Text(post.timestamp.toDate().toString())
62+
Padding(
63+
padding: EdgeInsets.fromLTRB(0, 15, 0, 15),
64+
child: Column(
65+
crossAxisAlignment: CrossAxisAlignment.start,
66+
children: [
67+
Text(post.text),
68+
SizedBox(height: 20),
69+
Text(post.timestamp.toDate().toString()),
70+
SizedBox(height: 20),
71+
IconButton(
72+
icon: new Icon(
73+
snapshotLike.data
74+
? Icons.favorite
75+
: Icons.favorite_border,
76+
color: Colors.blue,
77+
size: 30.0),
78+
onPressed: () {
79+
_postService.likePost(
80+
post, snapshotLike.data);
81+
}),
82+
Text(post.likesCount.toString())
83+
],
84+
),
85+
),
86+
Divider(),
5787
],
5888
),
59-
),
60-
Divider(),
61-
],
62-
),
63-
);
89+
);
90+
});
6491
});
6592
},
6693
);

frontend/lib/services/posts.dart

+36
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class PostService {
1414
text: doc.data()['text'] ?? '',
1515
creator: doc.data()['creator'] ?? '',
1616
timestamp: doc.data()['timestamp'] ?? 0,
17+
likesCount: doc.data()['likesCount'] ?? 0,
1718
);
1819
}).toList();
1920
}
@@ -26,6 +27,41 @@ class PostService {
2627
});
2728
}
2829

30+
Future likePost(PostModel post, bool current) async {
31+
print(post.id);
32+
if (current) {
33+
post.likesCount = post.likesCount - 1;
34+
await FirebaseFirestore.instance
35+
.collection("posts")
36+
.doc(post.id)
37+
.collection("likes")
38+
.doc(FirebaseAuth.instance.currentUser.uid)
39+
.delete();
40+
}
41+
if (!current) {
42+
post.likesCount = post.likesCount + 1;
43+
44+
await FirebaseFirestore.instance
45+
.collection("posts")
46+
.doc(post.id)
47+
.collection("likes")
48+
.doc(FirebaseAuth.instance.currentUser.uid)
49+
.set({});
50+
}
51+
}
52+
53+
Stream<bool> getCurrentUserLike(PostModel post) {
54+
return FirebaseFirestore.instance
55+
.collection("posts")
56+
.doc(post.id)
57+
.collection("likes")
58+
.doc(FirebaseAuth.instance.currentUser.uid)
59+
.snapshots()
60+
.map((snapshot) {
61+
return snapshot.exists;
62+
});
63+
}
64+
2965
Stream<List<PostModel>> getPostsByUser(uid) {
3066
return FirebaseFirestore.instance
3167
.collection("posts")

0 commit comments

Comments
 (0)