Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Set Up a Community-Driven Product Review System in FlutterFlow

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.

What you'll learn

  • How to build a star rating input with tappable Icon widgets
  • How to denormalize averageRating on the product document with Cloud Functions
  • How to track helpful votes while preventing duplicate voting
  • How to verify purchase status and display a verified badge on reviews
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner8 min read25-35 minFlutterFlow Pro+ (Cloud Functions for rating aggregation)March 2026RapidDev Engineering Team
TL;DR

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

1

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.

2

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.

3

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.

recalculate_rating.js
1// Cloud Function: recalculateRating
2const functions = require('firebase-functions');
3const admin = require('firebase-admin');
4admin.initializeApp();
5
6exports.recalculateRating = functions.firestore
7 .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();
13
14 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 });
21
22 const count = reviewsSnap.size;
23 const avg = count > 0 ? parseFloat((total / count).toFixed(1)) : 0;
24
25 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.

4

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.

5

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.

6

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

FlutterFlow Product Review System
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: String
8 rating: int (1-5)
9 title: String
10 body: String
11 imageUrls: [String]
12 helpfulCount: int (default 0)
13 isVerifiedPurchase: bool
14 timestamp: Timestamp
15 products/{id}/reviews/{id}/helpful_votes (subcollection):
16 Document ID = voter userId (prevents duplicates)
17
18PAGE: ProductDetail Rating Summary
19 Large Text: averageRating (e.g. 4.3)
20 Row: star Icons reflecting average
21 Text: "Based on {reviewCount} reviews"
22 Rating distribution:
23 5 Rows (5-star to 1-star):
24 Text (star level) + LinearPercentIndicator + count Text
25
26PAGE: ProductDetail Reviews List
27 Sort DropDown: Recent | Most Helpful | Highest | Lowest
28 ListView reviews subcollection (sorted by selection)
29 Review card:
30 Row: CircleImage (avatar) + displayName + Verified badge
31 Row: star Icons for this review's rating
32 Text: title (bold)
33 Text: body
34 Row: review images (if any)
35 Button: Helpful ({helpfulCount}) with thumbs-up icon
36 On tap: check helpful_votes create or show already voted
37
38PAGE: WriteReview
39 Row: 5 star Icons (tappable, amber filled / grey outline)
40 Text: rating label (Poor/Fair/Good/Very Good/Excellent)
41 TextField: review title
42 TextField: review body (multiline)
43 FlutterFlowUploadButton: optional photos
44 Button "Submit Review"
45 Validate rating > 0 + title not empty
46 Check orders for verified purchase
47 Create review doc (with isVerifiedPurchase)
48 Cloud Function recalculates product rating
49
50CLOUD FUNCTION: recalculateRating
51 Triggered on reviews subcollection write
52 Query all reviews compute avg, count, distribution
53 Update product document

Common 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.

ChatGPT Prompt

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.

FlutterFlow Prompt

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.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.