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

How to Build a Personalized News Feed in FlutterFlow

Build a personalized news feed by storing user interests during onboarding via ChoiceChips, then querying articles matching those interests from Firestore. Add engagement tracking (reads, likes, shares) to refine relevance scoring in a Cloud Function. Users toggle between a For You feed ranked by relevance and a Latest feed sorted chronologically. Mute topics to exclude unwanted categories. Pull-to-refresh loads the newest articles on demand.

What you'll learn

  • How to capture user interests during onboarding with ChoiceChips
  • How to query Firestore articles filtered by user interest categories
  • How to build a Cloud Function that scores articles by engagement relevance
  • How to implement For You vs Latest feed toggles with topic muting
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 relevance scoring)March 2026RapidDev Engineering Team
TL;DR

Build a personalized news feed by storing user interests during onboarding via ChoiceChips, then querying articles matching those interests from Firestore. Add engagement tracking (reads, likes, shares) to refine relevance scoring in a Cloud Function. Users toggle between a For You feed ranked by relevance and a Latest feed sorted chronologically. Mute topics to exclude unwanted categories. Pull-to-refresh loads the newest articles on demand.

Building an Interest-Based Personalized Feed in FlutterFlow

A generic chronological feed shows the same content to everyone. A personalized feed ranks and filters articles by what each user cares about. This tutorial captures user interests, queries matching articles, tracks engagement to improve relevance, and lets users fine-tune their feed with topic muting.

Prerequisites

  • FlutterFlow project with Firebase authentication
  • Firestore articles collection with category and publishedAt fields
  • Users collection with an interests array field
  • Basic familiarity with Backend Queries in FlutterFlow

Step-by-step guide

1

Capture user interests during onboarding with ChoiceChips

On the onboarding page, add a ChoiceChips widget with options matching your article categories: Tech, Science, Business, Sports, Entertainment, Health, Politics. Set the ChoiceChips to allow multiple selection and bind the selected values to a Page State variable selectedInterests (list of strings). On the Continue button, update the current user's Firestore document to set the interests array field to selectedInterests. Also store this in App State so the feed can query it immediately without an extra Firestore read.

Expected result: Users select their preferred topics during onboarding and the choices are saved to their Firestore user document.

2

Build the personalized feed with interest-based filtering

Create a FeedPage with a ListView bound to a Backend Query on the articles collection. Set the query to filter where category is in the current user's interests array, ordered by publishedAt descending. Each article card shows: an Image for the thumbnail, a Text for the category label (styled as a colored chip), the headline Text, a brief summary Text, and the author name with publish date. If the user has no interests set, show all articles sorted by publishedAt as a fallback.

Expected result: The feed shows only articles matching the user's selected interest categories, newest first.

3

Add For You vs Latest toggle with engagement scoring

Add ToggleButtons at the top of the feed page with two options: For You and Latest. Latest uses the basic chronological query from the previous step. For You requires a Cloud Function that pre-computes relevance scores. The function runs on a schedule or on article publish. It scores each article per user: interest match gets 10 points, recency within 24 hours gets 5 points, articles in categories the user has liked before get a bonus. Results are written to a users/{uid}/feed_ranked subcollection with articleId and score. The For You toggle queries this subcollection ordered by score descending.

compute_feed_ranking.js
1// Cloud Function: computeUserFeedRanking
2const functions = require('firebase-functions');
3const admin = require('firebase-admin');
4admin.initializeApp();
5
6exports.computeUserFeedRanking = functions.pubsub
7 .schedule('every 1 hours').onRun(async () => {
8 const usersSnap = await admin.firestore()
9 .collection('users').get();
10
11 for (const userDoc of usersSnap.docs) {
12 const interests = userDoc.data().interests || [];
13 const articlesSnap = await admin.firestore()
14 .collection('articles')
15 .where('category', 'in', interests.slice(0, 10))
16 .orderBy('publishedAt', 'desc')
17 .limit(50).get();
18
19 const batch = admin.firestore().batch();
20 for (const article of articlesSnap.docs) {
21 const score = calculateScore(article.data(), userDoc.data());
22 const ref = userDoc.ref
23 .collection('feed_ranked')
24 .doc(article.id);
25 batch.set(ref, { articleId: article.id, score });
26 }
27 await batch.commit();
28 }
29 });

Expected result: Users toggle between a relevance-ranked For You feed and a chronological Latest feed.

4

Track engagement signals for feed refinement

Create a Firestore collection user_engagements with fields: userId, articleId, eventType (view, like, share), category, timestamp. When a user taps an article to read it, create an engagement doc with eventType 'view'. Add a heart IconButton that toggles a like engagement. Add a share IconButton that logs a share event. The Cloud Function from the previous step reads these engagement docs to boost scores for categories the user interacts with most. For example, if a user reads 10 Tech articles but only 2 Sports articles, Tech articles get a higher relevance boost in future feed computations.

Expected result: User interactions (views, likes, shares) are tracked and influence future feed ranking calculations.

5

Implement topic muting to exclude unwanted categories

Add a settings section where users can mute specific topics. Create a Firestore field mutedTopics (array of strings) on the user document. On the feed page or in settings, show each category with a Mute/Unmute toggle (Switch widget). When a topic is muted, add it to the mutedTopics array. In the feed Backend Query, add a where clause excluding articles whose category is in mutedTopics. Alternatively, filter client-side if Firestore query limitations prevent combining whereIn with whereNotIn. This gives users control over their feed without changing their core interests.

Expected result: Muted topics are excluded from the feed, giving users fine-grained control over what they see.

6

Add pull-to-refresh for the latest articles

Wrap the feed ListView in a RefreshIndicator widget. On refresh, re-run the Backend Query to fetch the latest articles from Firestore. Display a brief loading indicator while the query executes. This lets users manually check for new content without waiting for automatic updates. For the For You feed, the refresh triggers a re-read of the feed_ranked subcollection. For Latest, it re-runs the chronological query with the latest publishedAt results.

Expected result: Pulling down on the feed refreshes the article list with the most recent content.

Complete working example

FlutterFlow Personalized News Feed
1FIRESTORE SCHEMA:
2 articles (collection):
3 title: String
4 summary: String
5 body: String
6 category: String
7 author: String
8 thumbnailUrl: String
9 publishedAt: Timestamp
10 users (collection):
11 interests: [String] (max 10)
12 mutedTopics: [String]
13 users/{uid}/feed_ranked (subcollection):
14 articleId: String
15 score: int
16 user_engagements (collection):
17 userId: String
18 articleId: String
19 eventType: String (view|like|share)
20 category: String
21 timestamp: Timestamp
22
23PAGE: Onboarding Interest Selection
24 ChoiceChips (Tech, Science, Business, Sports, etc.)
25 Max 10 selections
26 Button "Continue" update user doc interests array
27
28PAGE: FeedPage
29 ToggleButtons: For You | Latest
30 Page State: feedMode (forYou | latest)
31
32 FOR YOU MODE:
33 Backend Query: users/{uid}/feed_ranked orderBy score desc
34 fetch article docs by articleId
35
36 LATEST MODE:
37 Backend Query: articles where category IN user.interests
38 orderBy publishedAt desc
39 Exclude: category NOT IN user.mutedTopics
40
41 RefreshIndicator wrapping ListView
42 Each article card:
43 Image (thumbnail)
44 Container (category chip)
45 Text (headline)
46 Text (summary, maxLines 2)
47 Row: author + date + like IconButton + share IconButton
48 On tap: navigate to ArticleDetail + log view engagement
49
50SETTINGS: Topic Muting
51 ListView of all categories
52 Switch per category add/remove from mutedTopics array
53
54CLOUD FUNCTION: computeUserFeedRanking
55 Runs hourly
56 For each user: score articles by interest match + recency + engagement history
57 Write top 50 to feed_ranked subcollection

Common mistakes when building a Personalized News Feed in FlutterFlow

Why it's a problem: Querying articles with whereIn using more than 10 interest values

How to avoid: Cap user interest selections at 10. If you need more, batch into groups of 10, run separate queries, and merge the results client-side.

Why it's a problem: Running the relevance scoring algorithm on the client

How to avoid: Pre-compute relevance scores in a Cloud Function on a schedule or article publish trigger. The client just reads the pre-ranked feed_ranked subcollection.

Why it's a problem: Showing an empty feed when a new user has not selected interests yet

How to avoid: Add a fallback: if interests is empty or not set, query all articles ordered by publishedAt descending. Show a banner prompting the user to select interests for a personalized experience.

Best practices

  • Cap user interests at 10 to stay within Firestore whereIn limits
  • Pre-compute feed rankings server-side in Cloud Functions for performance
  • Track engagement signals to continuously improve personalization
  • Provide a Latest chronological option so users can escape the algorithm
  • Allow topic muting for fine-grained feed control beyond core interests
  • Show a fallback feed for new users before they select interests
  • Use pull-to-refresh so users can manually check for new content
  • Display category labels on article cards so users know why each article appears

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

Build a personalized news feed in FlutterFlow. Users select interests during onboarding via ChoiceChips (max 10). Articles are filtered by interest categories from Firestore. A Cloud Function computes relevance scores using engagement data. The feed has For You (ranked) and Latest (chronological) toggles. Users can mute topics. Include the Firestore schema and ranking function.

FlutterFlow Prompt

Create a feed page with ToggleButtons at the top (For You and Latest), a ListView below showing article cards with thumbnail image, category chip, headline, summary, and a like button. Add a RefreshIndicator wrapper.

Frequently asked questions

How many interest categories should I offer?

Keep it between 8 and 15 categories. Fewer than 8 feels limiting; more than 15 overwhelms users during onboarding. Remember Firestore whereIn supports a maximum of 10 selected values.

Can I update interests after onboarding?

Yes. Add an Edit Interests button on the settings or profile page that opens the same ChoiceChips interface. Update the user document on save and re-trigger the feed ranking Cloud Function.

How often should the ranking Cloud Function run?

Hourly is a good starting point. For high-volume apps, run it on each new article publish using a Firestore trigger. For low-volume apps, every few hours is sufficient.

Can I add a trending section alongside personalized content?

Yes. Query articles from the past 24 hours ordered by a combined engagement count (views plus likes). Display the top five as a Trending horizontal carousel above the main feed.

How do I handle articles in categories the user has not selected?

By default they are excluded from the For You feed. The Latest feed can optionally show all categories. You can also add a Discover section showing popular articles outside the user's interests to encourage exploration.

Can RapidDev help build a personalized content platform?

Yes. RapidDev can build recommendation engines, personalized feeds, engagement tracking, and content management systems tailored to your audience and content types.

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.