Implementing Syde An online Forum in Flutter (Update 2 : Post A Story, Retrieve All Stories)
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
then
callback 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 [email protected] you want to make this application better, you can make a Pull Request.
Github
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Thanks for the review... I'll improve on my next contribution
Thank you for your review, @helo! Keep up the good work!
Hi, @ideba!
You just got a 0.7% upvote from SteemPlus!
To get higher upvotes, earn more SteemPlus Points (SPP). On your Steemit wallet, check your SPP balance and click on "How to earn SPP?" to find out all the ways to earn.
If you're not using SteemPlus yet, please check our last posts in here to see the many ways in which SteemPlus can improve your Steem experience on Steemit and Busy.
Hi @ideba!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server
Hey, @ideba!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
Congratulations @ideba! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
You can view your badges on your Steem Board and compare to others on the Steem Ranking
If you no longer want to receive notifications, reply to this comment with the word
STOP
Do not miss the last post from @steemitboard:
Vote for @Steemitboard as a witness to get one more award and increased upvotes!