Build product recommendations by tracking user events (views, cart adds, purchases) in Firestore. A Cloud Function runs collaborative filtering: finds co-viewed and co-purchased products, scores them, and writes the top 10 to each user's recommendations subcollection. Display a Recommended for You carousel on the home page and a Customers Also Bought section on product pages. Each recommendation includes a reason string explaining the suggestion.
Building a Behavior-Based Recommendation Engine in FlutterFlow
Product recommendations drive 35% of Amazon's revenue. This tutorial builds a recommendation engine for your FlutterFlow e-commerce app by tracking what users view, add to cart, and buy, then using collaborative filtering in Cloud Functions to suggest products they are likely to want. Recommendations are pre-computed and stored in Firestore for instant display.
Prerequisites
- FlutterFlow project with a products collection in Firestore
- Firebase authentication enabled
- Users browsing and purchasing products in your app
- Cloud Functions enabled for batch recommendation processing
Step-by-step guide
Create the Firestore schema for behavior tracking and recommendations
Create the Firestore schema for behavior tracking and recommendations
Create a user_events collection with fields: userId (String), productId (String), eventType (String: 'view', 'addToCart', 'purchase', 'wishlist'), category (String, denormalized from product), timestamp (Timestamp). Create a subcollection users/{uid}/product_recommendations with fields: productId (String), score (double), reason (String, e.g., 'Customers who viewed X also bought this'), updatedAt (Timestamp). The events collection captures raw behavior data. The recommendations subcollection stores pre-computed results for instant reads. Keep the event weights different: purchase = 10 points, addToCart = 5, wishlist = 3, view = 1.
Expected result: Firestore has collections for tracking user behavior events and storing pre-computed recommendations.
Track user behavior events throughout the app
Track user behavior events throughout the app
Add event logging at key interaction points using Action Flows. On product detail page load: create a user_events document with eventType 'view'. On Add to Cart button tap: create an event with 'addToCart'. On successful order completion: create events with 'purchase' for each item in the order. On wishlist toggle: create an event with 'wishlist'. Each event includes the userId, productId, product category (for category-level recommendations), and the current timestamp. Keep event logging as a non-blocking action: do not await the Firestore write so it does not slow down the user's interaction.
Expected result: All user product interactions are captured as events in Firestore for recommendation processing.
Build the Cloud Function for collaborative filtering recommendations
Build the Cloud Function for collaborative filtering recommendations
Deploy a scheduled Cloud Function called computeRecommendations that runs every 6 hours. For each active user (has events in the last 30 days), the function: (1) Gets the user's recent product interactions weighted by event type. (2) For each product the user interacted with, finds other users who also interacted with that product. (3) Gets products those other users interacted with that the current user has NOT seen. (4) Scores each candidate product by how many co-users interacted with it, weighted by their event types. (5) Writes the top 10 scored products to the user's product_recommendations subcollection with the score and a reason string explaining the connection.
1// Cloud Function: computeRecommendations (simplified)2const functions = require('firebase-functions');3const admin = require('firebase-admin');4admin.initializeApp();56const WEIGHTS = { purchase: 10, addToCart: 5, wishlist: 3, view: 1 };78exports.computeRecommendations = functions.pubsub9 .schedule('every 6 hours').onRun(async () => {10 const db = admin.firestore();11 const thirtyDaysAgo = new Date(Date.now() - 30 * 86400000);12 13 // Get active users14 const activeEvents = await db.collection('user_events')15 .where('timestamp', '>', thirtyDaysAgo)16 .get();17 18 const userProducts = {}; // userId -> [{productId, weight}]19 activeEvents.forEach(doc => {20 const e = doc.data();21 if (!userProducts[e.userId]) userProducts[e.userId] = {};22 const w = WEIGHTS[e.eventType] || 1;23 userProducts[e.userId][e.productId] =24 (userProducts[e.userId][e.productId] || 0) + w;25 });26 27 for (const [userId, products] of Object.entries(userProducts)) {28 const userProductIds = Object.keys(products);29 const candidates = {};30 31 // Find co-users and their products32 for (const pid of userProductIds.slice(0, 20)) {33 const coEvents = await db.collection('user_events')34 .where('productId', '==', pid)35 .where('userId', '!=', userId)36 .limit(50).get();37 38 for (const doc of coEvents.docs) {39 const ce = doc.data();40 if (!userProductIds.includes(ce.productId)) {41 // This is unseen by our user — not in their products42 }43 // Get co-user's other products44 const coUserEvents = await db.collection('user_events')45 .where('userId', '==', ce.userId)46 .limit(20).get();47 coUserEvents.forEach(d => {48 const oe = d.data();49 if (!userProductIds.includes(oe.productId)) {50 if (!candidates[oe.productId]) {51 candidates[oe.productId] = { score: 0, reason: pid };52 }53 candidates[oe.productId].score += WEIGHTS[oe.eventType] || 1;54 }55 });56 }57 }58 59 // Write top 1060 const top10 = Object.entries(candidates)61 .sort((a, b) => b[1].score - a[1].score)62 .slice(0, 10);63 64 const batch = db.batch();65 // Clear old recommendations66 const oldRecs = await db.collection('users').doc(userId)67 .collection('product_recommendations').get();68 oldRecs.forEach(d => batch.delete(d.ref));69 70 for (const [prodId, data] of top10) {71 const ref = db.collection('users').doc(userId)72 .collection('product_recommendations').doc(prodId);73 batch.set(ref, {74 productId: prodId,75 score: data.score,76 reason: `Because you viewed a related product`,77 updatedAt: admin.firestore.FieldValue.serverTimestamp(),78 });79 }80 await batch.commit();81 }82 });Expected result: The Cloud Function processes user behavior data and writes personalized product recommendations to each user's subcollection.
Display Recommended for You carousel on the home page
Display Recommended for You carousel on the home page
On the home page, add a section titled Recommended for You. Add a horizontal ListView bound to a Backend Query on the current user's product_recommendations subcollection, ordered by score descending, limited to 10. For each recommendation, fetch the product document using the productId to get the product image, name, and price. Display each as a card in the horizontal list: product image (using the CachedImage or thumbnail URL), product name, price, and a small Text showing the reason (e.g., 'Because you viewed Wireless Headphones'). Tapping a card navigates to the product detail page. If the user has no recommendations yet (new user), show a Popular Products section as a fallback.
Expected result: The home page shows a personalized horizontal carousel of recommended products with explanation reasons.
Add Customers Also Bought section on product detail pages
Add Customers Also Bought section on product detail pages
On the product detail page, add a section below the product information titled Customers Also Bought. This uses a different approach than the personalized recommendations: query user_events where productId equals the current product and eventType equals 'purchase'. Collect the userIds of those buyers. Then query their other purchase events to find the most commonly co-purchased products. This can be pre-computed by a Cloud Function that maintains a co_purchases map on each product document: a map of productId to co-purchase count. Display the top 5 co-purchased products as a horizontal ListView with product cards. This section is the same for all users viewing this product, unlike the personalized home page carousel.
Expected result: Product detail pages show frequently co-purchased products, encouraging additional purchases.
Complete working example
1FIRESTORE SCHEMA:2 user_events (collection):3 userId: String4 productId: String5 eventType: String (view|addToCart|purchase|wishlist)6 category: String (denormalized)7 timestamp: Timestamp8 users/{uid}/product_recommendations (subcollection):9 productId: String10 score: double11 reason: String12 updatedAt: Timestamp13 products (add field):14 coPurchases: Map<productId, count> (precomputed)1516EVENT WEIGHTS:17 purchase: 10, addToCart: 5, wishlist: 3, view: 11819EVENT TRACKING (Action Flows):20 Product detail page load → log 'view' event21 Add to Cart tap → log 'addToCart' event22 Order complete → log 'purchase' event per item23 Wishlist toggle → log 'wishlist' event24 All non-blocking (fire and forget)2526CLOUD FUNCTION: computeRecommendations27 Schedule: every 6 hours28 For each active user:29 1. Get weighted product interactions (last 30 days)30 2. Find co-users who interacted with same products31 3. Get co-users' other products (user hasn't seen)32 4. Score candidates by weighted co-interaction count33 5. Write top 10 to product_recommendations subcollection34 Each recommendation includes reason string3536PAGE: HomePage — Recommended for You37 Section title: "Recommended for You"38 ListView.horizontal:39 Backend Query: product_recommendations orderBy score desc limit 1040 Each card: product image + name + price + reason text41 Fallback (no recs): show Popular Products4243PAGE: ProductDetail — Customers Also Bought44 Section title: "Customers Also Bought"45 ListView.horizontal:46 Read product.coPurchases map → top 5 products47 Each card: product image + name + priceCommon mistakes when building a Behavior-Based Product Recommendation System in FlutterFlow
Why it's a problem: Running the recommendation algorithm on the client
How to avoid: Run the recommendation algorithm in a Cloud Function. The client only reads pre-computed results from the product_recommendations subcollection, which is fast and secure.
Why it's a problem: Not deduplicating view events for the same product
How to avoid: Before logging a view event, check if one already exists for this user and product within the last hour. Skip the duplicate. Alternatively, deduplicate during the recommendation computation.
Why it's a problem: Showing recommendations without any explanation
How to avoid: Include a reason string with each recommendation: 'Because you viewed X', 'Customers who bought Y also bought this', or 'Popular in your favorite category'. This builds trust and increases click-through.
Best practices
- Run recommendation computations server-side in Cloud Functions on a schedule
- Weight different behavior types: purchases matter more than views
- Include a reason string with each recommendation for transparency
- Pre-compute co-purchase data on product documents for instant detail page reads
- Deduplicate view events to avoid inflating signals from page refreshes
- Show a Popular Products fallback for new users without enough behavior data
- Limit recommendation computation to active users (events in last 30 days) to save resources
- Refresh recommendations every 6 hours for a balance of freshness and compute cost
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
Build a product recommendation engine for a FlutterFlow e-commerce app. Track user events (view, addToCart, purchase, wishlist) in Firestore. Create a Cloud Function that runs collaborative filtering: find co-users, score unseen products, write top 10 recommendations per user with reason strings. Display recommendations in a horizontal carousel on the home page and co-purchased products on detail pages. Include the Firestore schema and Cloud Function code.
Create a Recommended for You section on the home page with a horizontal ListView showing product cards. Each card has a product image, name, price, and a small grey text below saying the recommendation reason. Add a See All button at the end of the list.
Frequently asked questions
How many behavior events do I need before recommendations work well?
Collaborative filtering needs a critical mass of data. Aim for at least 100 active users with 10+ events each before expecting meaningful recommendations. For new apps, use category-based popular products as a fallback until you have enough data.
Can I mix collaborative filtering with content-based recommendations?
Yes. Content-based recommendations use product attributes (category, tags, price range) to suggest similar items. Combine both: collaborative filtering for personalized suggestions and content-based for product detail page similarity. Weight and merge the scores.
How do I prevent recommending products users already purchased?
In the Cloud Function, filter out products the user has already purchased (eventType purchase) from the candidate list. For consumable products that can be re-purchased, you may want to keep them but lower their score.
Will this work for apps with a small product catalog?
With fewer than 50 products, collaborative filtering adds limited value since users naturally discover most products. For small catalogs, use simpler approaches: category-based suggestions, trending products, or hand-curated collections.
How much does the recommendation Cloud Function cost?
Cost depends on the number of active users and events. For 1,000 users with 10,000 events, running every 6 hours costs roughly $5-15 per month in Cloud Functions compute. Monitor execution time and optimize queries to control costs.
Can RapidDev help build recommendation systems?
Yes. RapidDev can build sophisticated recommendation engines with collaborative filtering, content-based filtering, real-time personalization, A/B testing of algorithms, and analytics dashboards to measure recommendation effectiveness.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation