Repository
https://github.com/enyason/Syde
History
- Implementing Syde An online Forum in Flutter (Update: Authenticate With Google)
- Implementing Syde(An online Forum) in Flutter
New Features
- Create and post a new Story
- Display All Stories in Home Screen with a List
- Detailed Screen for the Stories
- Post Reaction Implementation (e.g like or unlike a story)
Create And Save a New Story
As part of the functionalities of SYDE, users on the platform can post their stories to the platform. This feature which is part of the back-end implementation is Handled by Fire-base.
Implementation
Implementing this part of the platform, FireStore of FireBase was used. FireStore NoSQL cloud database to store and sync data for a client- and server-side development. Firebase handles most of the back-end complexities allow the developer to focus on implementing important features of a product
The code block below is a method that handles creating a new story.
void makePost({String body, List images}) { images = ["image001", "image002"]; Firestore.instance.collection("all_post").add({ "post_id": "not available", "time_stamp": DateTime.now().millisecondsSinceEpoch.toString(), "user":{ "user_id": _user.uid, "user_name": _user.displayName, "user_photo": _user.photoUrl, }, "post_body": body, "like_count": 0, "comment_count": 0, "image_url": images }).then((docRef) { docRef.updateData({"post_id": docRef.documentID}); Navigator.pop(context); print(docRef.documentID); }); }- The method accepts the story content with images if available. Data Storage is not implemented yet with Firebase so we just use a dummy list with fake data.
- Firestore works with Collections and documents. So we get a firestore instance and get reference to a collection and add a new map.
- In the Map, we have defined all the post attribute.
- The
thencallback returns the document reference which is used to update the story id ()"post_id)
Retrieve All Stories and Display in Home Screen with a List
Users can view all stories made on the platform by navigating to the story tab. The Stories are displayed as a list of items, which users can scroll through.
Implementation
With Firestore i listen to the document reference created by the "all_post" collection using Flutter out of the box stream builder Widget.
StreamBuilder<QuerySnapshot>(
//listen to changes in the document reference
stream: Firestore.instance
.collection('all_post')
.orderBy("time_stamp", descending: true)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> document) {
//return error message if there is an error
if (document.hasError)
return Center(child: Text('Error: ${document.error}'));
switch (document.connectionState) {
case ConnectionState.waiting:
//show progress dialog while state is waiting
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue)));
default:
// returns a listView : builds children lazily
return ListView.builder(
itemCount: document.data.documents.length,
itemBuilder: (context, index) {
...
});})
Internally, the stream builder subscribes to the firstore to receive changes in real time.D epending on return values from firebase, the appropriate UI is displayed
Detailed Screen for the Stories
Implementation
For the detailed screen, I created a model class that has fields related to a story. The Story object is passed onto the detail screen which provides the contents that will be displayed on the Screen.
class Store{
String storyTitle,storyBody,storyId,timeStamp;
int likeCount,commentCount;
Map user;
//cretates story from a map
Story.fromMap(Map story){
storyTitle = "Not Available";
storyBody = story["post_body"];
storyId = story["post_id"];
timeStamp = story["time_stamp"];
user = story["user"];
likeCount = story["like_count"];
commentCount = story["commentCount"];
}
}
The Model class defines required attributes that will be needed structuring the UI
Post Reaction Implementation
Users can react to a story made by a user in the platform . They can either like it or unlike it.
Like Implementation
// this method handles liking a psot
likePost(int index, AsyncSnapshot<QuerySnapshot> document) async {
//use transaction on the fire store instance to prevent race condition
Firestore.instance.runTransaction((transaction) async {
//get a document snapshot at the current position
DocumentSnapshot snapshot =
await transaction.get(document.data.documents[index].reference);
//include uid to the like collection of the story
// and set "like" field to true
await transaction.set(
snapshot.reference.collection("likes").document(widget.user.uid),
{"like": true});
//increment like count for the story
await transaction.update(snapshot.reference,
{"like_count": document.data.documents[index]["like_count"] + 1});
});
}
Here I used firebase transaction so we don't have issues of race condition. Suppose multiple users are updating the value of data at the same time, we could get unexpected results. To handle this, firebase provides an atomic operation called Transaction.
Unlike Implementation
//this method handles unlike a post
unLikePost(int index, AsyncSnapshot<QuerySnapshot> document) async {
Firestore.instance.runTransaction((transaction) async {
DocumentSnapshot snapshot =
await transaction.get(document.data.documents[index].reference);
//unlike only when like count is > 0
if (document.data.documents[index]["like_count"] > 0) {
// and set "like" field to false
await transaction.set(
snapshot.reference.collection("likes").document(widget.user.uid),
{"like": false});
// decrement like count
await transaction.update(snapshot.reference,
{"like_count": document.data.documents[index]["like_count"] - 1});
}
});
}
This implementation is similar to that of the like.
IMPORTANT RESOURCES
*Github *: https://github.com/enyason/Syde
RoadMap
Authenticate UserPersisting user postDisplaying all postDetailed screen implementationStory Reaction Implementation (like and unlike a story)- Searching all posts
- Providing different layouts
- ToDo for users to track their daily progress
- Push Notifications
- Posts sharing
- Users dashboard
- Searching all users
- Direct Messaging with Users
- ChatGroup
- Bookmarking post
Demo Video
How to contribute?
You can reach me by commenting on this post or send a message via enyasonjnr@gmail.com.If you want to make this application better, you can make a Pull Request.
Github