You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
- SendGrid V3 Transactional Email Cloud Function
- AngularFire2 State Changes With NgRx
- CSV Exports From Firestore Database With Cloud Functions
- Multi-Step Signup With Firebase Email Auth and Angular Reactive Forms
- Angular SEO Part 2 - Firebase Cloud Functions Middleware for Rendertron
- Angular SEO Part 1 - Full Search Engine Optimization Solution for PWAs
- Progressive Web App Content Management With Contentful
- Multiple Device Push Notifications With FCM and Firestore
- Faster Firestore With Cloud Functions Data Aggregation
- Infinite Scroll and Pagination With Firestore and Angular
Reddit Style Upvoting in Angular 4 and Firebase NoSQLEpisode 13 by Jeff Delaney
UPDATE October 2017: This lesson uses AngularFire Version 4. The API has since been updated to version 5 with breaking changes. Firebase also released the new Firestore document database with many awesome features. Please read the V5 Firestore Upgrade Guide to learn how to use the latest and greatest technologies with this tutorial.
Upvoting and downvoting is an excellent ay handle community-driven content curation. Reddit is the most famous example of this feature, but it is common throughout the interwebs on places like StackOverflow, Kaggle, and others. In this lesson, we will use Angular 4 and Firebase to implement upvoting with ease.
You need to have user authentication wired up. You also need some other resource in the database that can upvoted, such posts, comments, items, etc. Check out these lessons if you get lost.
Our database needs to answer two questions as efficiently as possible. (1) Did this user vote for an item? (2) How many people voted on an item?
We can answer these questions by creating a collection of itemIds (using the firebase $key for items), with each document containing key-value pairs of userIDs (auth uid). The key is the userId and the value is their vote, which can be +1, 0, or –1.
To answer the first question, we can query the table with the itemId, then see if there is an existing userId key and vote value. We answer the second question by counting get the sum of the vote values.
We will use a service to query Firebase for the upvote data. First, we need a function to get the document for a specific item as a
FirebaseObjectObservable. Next, we need to update the document when the user casts a vote. Here we sent the object key equal to the userId, then update the document with vote value.
An example of the upvote feature UI with Firebase updating in realtime
Most of the work will happen in the component. First, we are passing the component an itemId and userId via the
@Input() decorator. Again, check out the prerequisites if you’re app still needs authentication. It should look like this:
Here’s how the component works step-by-step.
1 The input values are passed from the parent component, then used to interact with the service. We also set variables that will hold the user’s current vote and the total vote count for an item.
2 After injecting the service, we use the
getItemVotes() function and subscribe to the observable that it returns. The emitted value is a document of userIds and vote values from the database. If a userID is present, we check for the matching userId to see if a vote has cast.
Lodash is used to calculate the total vote count. The
values function converts the object values into an array, then
4 Now we need functions to let the user upvote and downvote. Each of these functions are identical - only the vote value is different, +1 for up and –1 for down. To facilitate the cancellation of votes, a ternary if operator is used to determine a value. It reads like this. “If you already upvoted, then I set your vote to 0, otherwise I set it to 1”.
Lastly, don’t forget to destroy the subscription. If your app has a large amount of content, this feature could definitely introduce memory leaks.
When the user clicks an arrow, their vote is cast by calling either the upvote or downvote function. The
ngClass directive is used to apply an active class when the user vote is valued at 1 or –1. In this case, an upvote is colored green and a downvote is red.
And let’s finish this off with some CSS. FontAwesome was used for the arrow icons, BTW.
Thats’s it for Reddit voting. Good luck!