Build a product review system with a star rating selector (5 tappable Icons), text reviews with optional photo uploads, and helpful vote tracking. Denormalize averageRating and reviewCount on each product document and recalculate via Cloud Function on every new review. Display rating distribution bars (5-star through 1-star percentages), sort reviews by recent, helpful, or rating, and show a verified purchase badge by checking if the reviewer has a completed order for that product.
Building a Community Product Review System in FlutterFlow
Product reviews build trust and drive purchase decisions. This tutorial creates a complete review system with star ratings, text and photo reviews, helpful voting, verified purchase verification, and aggregate rating display. Cloud Functions handle the math so product pages load fast with pre-computed averages.
Prerequisites
- FlutterFlow project with Firestore products collection
- Firebase authentication enabled
- Orders collection for verified purchase checking
- Basic familiarity with subcollections in Firestore
Step-by-step guide
Create the Firestore schema for reviews and helpful votes
Create the Firestore schema for reviews and helpful votes
Add a subcollection reviews under each product document with fields: userId (String), rating (int, 1-5), title (String), body (String), imageUrls (list of Strings), helpfulCount (int, default 0), timestamp (Timestamp). Add a subcollection helpful_votes under each review with the document ID being the voter's userId (prevents duplicate votes). On the product document, add denormalized fields: averageRating (double), reviewCount (int), ratingDistribution (map: {'1': count, '2': count, ...}). These denormalized fields are updated by Cloud Functions so the product page never needs to read all reviews just to display the average.
Expected result: Products have a reviews subcollection with helpful vote tracking and denormalized rating fields on the product doc.
Build the star rating input with tappable Icons
Build the star rating input with tappable Icons
On the Write Review page, create a Row with five Icon widgets. Use a Page State variable selectedRating (int, default 0). Each star Icon checks: if its position (1-5) is less than or equal to selectedRating, show Icons.star in amber; otherwise show Icons.star_border in grey. Each star's On Tap action sets selectedRating to that star's position number. Below the stars, add a Text showing the rating label: 1 = Poor, 2 = Fair, 3 = Good, 4 = Very Good, 5 = Excellent. Add TextFields for title and body (multiline), and a FlutterFlowUploadButton for optional review photos.
Expected result: Users tap stars to select a 1-5 rating, with filled stars showing their selection and a text label for each rating level.
Submit the review and trigger rating recalculation
Submit the review and trigger rating recalculation
The Submit Review button runs an Action Flow: validate that selectedRating is greater than 0 and title is not empty. Create a document in the products/{productId}/reviews subcollection with the rating, title, body, imageUrls (from upload), userId, and timestamp. After creation, call a Cloud Function recalculateRating(productId) that queries all reviews for that product, computes the new averageRating, reviewCount, and ratingDistribution map, then updates the product document. This keeps the product page fast since it reads pre-computed values instead of aggregating on every load.
1// Cloud Function: recalculateRating2const functions = require('firebase-functions');3const admin = require('firebase-admin');4admin.initializeApp();56exports.recalculateRating = functions.firestore7 .document('products/{productId}/reviews/{reviewId}')8 .onWrite(async (change, context) => {9 const productId = context.params.productId;10 const reviewsSnap = await admin.firestore()11 .collection('products').doc(productId)12 .collection('reviews').get();1314 let total = 0;15 const dist = { '1': 0, '2': 0, '3': 0, '4': 0, '5': 0 };16 reviewsSnap.forEach(doc => {17 const r = doc.data().rating;18 total += r;19 dist[String(r)]++;20 });2122 const count = reviewsSnap.size;23 const avg = count > 0 ? parseFloat((total / count).toFixed(1)) : 0;2425 await admin.firestore().collection('products')26 .doc(productId).update({27 averageRating: avg,28 reviewCount: count,29 ratingDistribution: dist,30 });31 });Expected result: Submitting a review creates the review document and automatically recalculates the product's average rating.
Display rating summary with distribution bars
Display rating summary with distribution bars
On the product detail page, add a rating summary section. Show the averageRating as a large Text (e.g., 4.3) next to a Row of filled/empty star Icons reflecting the average. Show reviewCount as text below (e.g., 'Based on 47 reviews'). For the distribution bars: create five Rows, one for each star level (5 down to 1). Each Row shows: the star number Text, a LinearPercentIndicator where the percentage is ratingDistribution[starLevel] divided by reviewCount, and the count Text. This gives users a quick visual breakdown of how ratings are distributed.
Expected result: The product page shows the average rating, star display, total count, and a bar chart of rating distribution.
Add helpful voting with duplicate prevention
Add helpful voting with duplicate prevention
On each review card, add a Helpful button showing the helpfulCount and a thumbs-up Icon. On tap, check if a document exists in the review's helpful_votes subcollection with the current user's ID. If it exists, show a SnackBar saying they already voted. If not, create the vote document and increment the review's helpfulCount using FieldValue.increment(1). Using the userId as the document ID guarantees uniqueness at the Firestore level, preventing race condition double-votes even if the client check is bypassed. Add a sort option to order reviews by helpfulCount descending so the most useful reviews appear first.
Expected result: Users can mark reviews as helpful once, with the count displayed and used for sorting.
Show verified purchase badges on reviews
Show verified purchase badges on reviews
When displaying each review, check if the reviewer has a completed order containing this product. Query the orders collection where userId equals the reviewer's ID, status equals 'completed', and the items array contains the current productId. If a matching order exists, show a green Container badge with a checkmark Icon and the text 'Verified Purchase' next to the reviewer name. This check can be done via a Backend Query on each review card or pre-computed by the Cloud Function at review submission time (store isVerifiedPurchase boolean on the review document for faster reads).
Expected result: Reviews from users who actually purchased the product display a Verified Purchase badge.
Complete working example
1FIRESTORE SCHEMA:2 products (collection):3 averageRating: double (denormalized)4 reviewCount: int (denormalized)5 ratingDistribution: map {1: count, 2: count, ...}6 products/{id}/reviews (subcollection):7 userId: String8 rating: int (1-5)9 title: String10 body: String11 imageUrls: [String]12 helpfulCount: int (default 0)13 isVerifiedPurchase: bool14 timestamp: Timestamp15 products/{id}/reviews/{id}/helpful_votes (subcollection):16 Document ID = voter userId (prevents duplicates)1718PAGE: ProductDetail — Rating Summary19 Large Text: averageRating (e.g. 4.3)20 Row: star Icons reflecting average21 Text: "Based on {reviewCount} reviews"22 Rating distribution:23 5 Rows (5-star to 1-star):24 Text (star level) + LinearPercentIndicator + count Text2526PAGE: ProductDetail — Reviews List27 Sort DropDown: Recent | Most Helpful | Highest | Lowest28 ListView → reviews subcollection (sorted by selection)29 Review card:30 Row: CircleImage (avatar) + displayName + Verified badge31 Row: star Icons for this review's rating32 Text: title (bold)33 Text: body34 Row: review images (if any)35 Button: Helpful ({helpfulCount}) with thumbs-up icon36 On tap: check helpful_votes → create or show already voted3738PAGE: WriteReview39 Row: 5 star Icons (tappable, amber filled / grey outline)40 Text: rating label (Poor/Fair/Good/Very Good/Excellent)41 TextField: review title42 TextField: review body (multiline)43 FlutterFlowUploadButton: optional photos44 Button "Submit Review"45 → Validate rating > 0 + title not empty46 → Check orders for verified purchase47 → Create review doc (with isVerifiedPurchase)48 → Cloud Function recalculates product rating4950CLOUD FUNCTION: recalculateRating51 Triggered on reviews subcollection write52 Query all reviews → compute avg, count, distribution53 Update product documentCommon mistakes
Why it's a problem: Recalculating average rating by querying all reviews on every page load
How to avoid: Denormalize: store averageRating and reviewCount on the product document. Update via Cloud Function on every review write. The product page reads one document instead of hundreds.
Why it's a problem: Allowing duplicate helpful votes by only checking client-side
How to avoid: Use the voter's userId as the document ID in the helpful_votes subcollection. Firestore rejects duplicate document IDs, preventing double votes at the database level.
Why it's a problem: Not verifying purchase status before showing the verified badge
How to avoid: Verify purchase in the Cloud Function at review submission time by querying the orders collection server-side. Store the result as isVerifiedPurchase on the review document.
Best practices
- Denormalize averageRating and reviewCount on the product document for fast reads
- Use Cloud Functions to recalculate ratings server-side on every review change
- Prevent duplicate helpful votes using the userId as the document ID
- Pre-compute verified purchase status at review submission time
- Show rating distribution bars so users see the full picture, not just the average
- Allow sorting reviews by recent, helpful, and rating for different browsing needs
- Require a minimum rating selection before allowing review submission
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
Build a product review system in FlutterFlow with Firestore. I need: star rating input (5 tappable stars), text reviews with photo upload, helpful voting with duplicate prevention, verified purchase badges, denormalized averageRating on the product doc recalculated by Cloud Function, and rating distribution bars. Include the Firestore schema and Cloud Function code.
Create a product reviews section with a rating summary (large average number, star icons, review count, five distribution bars) at the top, followed by a ListView of review cards each showing stars, title, body, helpful button, and a verified purchase badge.
Frequently asked questions
How do I prevent fake or spam reviews?
Require authentication for all reviews. Add rate limiting (one review per product per user). Use the verified purchase badge to highlight genuine buyers. For advanced moderation, add a Cloud Function that flags reviews with profanity or suspicious patterns for manual review.
Can users edit or delete their own reviews?
Yes. Show Edit and Delete buttons only on reviews where userId matches the current user. Edit opens the review form pre-filled with existing data. Delete removes the review document. Both trigger the rating recalculation Cloud Function.
How do I show reviews with photos prominently?
Add a With Photos filter option that queries reviews where imageUrls array is not empty. Display a photo gallery row at the top of the reviews section showing thumbnail images from all reviews with photos.
Can I add review responses from the product owner?
Yes. Add a response field on the review document. Product owners (identified by role) see a Reply button on each review. The response displays below the review body with a distinct background color and the label 'Response from seller'.
How do I handle the star rating for products with very few reviews?
Show the star rating only when reviewCount is above a threshold (e.g., 3 reviews). Below that, show 'Not enough reviews' to avoid misleading averages from one or two reviews.
Can RapidDev help build a review and rating platform?
Yes. RapidDev can build comprehensive review systems with sentiment analysis, photo moderation, verified purchase verification, seller response workflows, and review analytics dashboards.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation