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

How to Implement a Dynamic Sorting Algorithm for Search Results in FlutterFlow

Implement dynamic search result sorting by building a Custom Function that scores results based on multiple weighted factors: text match quality, recency, popularity via view count, and user personalization from past interactions. Fetch a candidate set from Firestore with basic filtering, run the scoring function to rank results, and display them in a ListView with highlighted match terms. Optionally integrate Algolia for full-text search with typo tolerance and faceted filtering.

What you'll learn

  • How to build a multi-factor relevance scoring Custom Function
  • How to fetch and rank search results efficiently from Firestore
  • How to highlight matching search terms in result text
  • How to integrate Algolia for full-text search with typo tolerance
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner8 min read25-35 minFlutterFlow Free+March 2026RapidDev Engineering Team
TL;DR

Implement dynamic search result sorting by building a Custom Function that scores results based on multiple weighted factors: text match quality, recency, popularity via view count, and user personalization from past interactions. Fetch a candidate set from Firestore with basic filtering, run the scoring function to rank results, and display them in a ListView with highlighted match terms. Optionally integrate Algolia for full-text search with typo tolerance and faceted filtering.

Implementing Dynamic Search Result Sorting in FlutterFlow

Basic search shows results in whatever order the database returns them. Dynamic sorting ranks results by relevance using multiple factors so the best match appears first. This tutorial builds a scoring algorithm that weights text match quality, content recency, popularity, and user preferences, then displays ranked results with highlighted match terms.

Prerequisites

  • A FlutterFlow project with Firestore containing searchable content
  • A collection with fields like title, description, viewCount, and timestamp
  • Basic familiarity with Custom Functions in FlutterFlow
  • An Algolia account (optional, for advanced full-text search)

Step-by-step guide

1

Set up the search data model and candidate fetching

Ensure your searchable collection (e.g., articles, products, or listings) has fields: title (String), description (String), category (String), viewCount (Integer), timestamp (Timestamp), tags (String Array). Add a titleLowerCase field that stores the lowercase version of the title for case-insensitive searching. On the SearchPage, add a TextField for the search query. When the user types and presses search, execute a Backend Query on the collection. Use a whereIn or arrayContainsAny filter on tags if applicable, or use a range query on titleLowerCase with startAt and endAt for prefix matching. Limit results to 100 candidates to keep client-side scoring fast.

Expected result: A search query fetches up to 100 candidate results from Firestore for client-side ranking.

2

Build the multi-factor scoring Custom Function

Create a Custom Function named scoreAndRankResults that takes the search query string and the list of candidate documents as inputs. For each candidate, calculate a relevance score based on weighted factors. Title contains the exact query: add 10 points. Title starts with the query: add 5 bonus points. Description contains the query: add 3 points. Recency: calculate days since timestamp, score = max(0, 5 minus days divided by 30) so newer content scores higher up to 5 points. Popularity: score = min(5, viewCount divided by 100) capping at 5 points. Personalization: if the item's category matches any category the user has viewed before (stored in App State recentCategories), add 3 points. Sum all factors into a total score. Sort the list by score descending and return it.

score_and_rank_results.dart
1// Custom Function: scoreAndRankResults
2double scoreItem(Map<String, dynamic> item, String query, List<String> userCategories) {
3 double score = 0;
4 final title = (item['title'] as String).toLowerCase();
5 final desc = (item['description'] as String).toLowerCase();
6 final q = query.toLowerCase();
7
8 // Text match scoring
9 if (title.contains(q)) score += 10;
10 if (title.startsWith(q)) score += 5;
11 if (desc.contains(q)) score += 3;
12
13 // Recency scoring (max 5 points)
14 final days = DateTime.now().difference(item['timestamp'].toDate()).inDays;
15 score += (5 - (days / 30)).clamp(0, 5);
16
17 // Popularity scoring (max 5 points)
18 score += ((item['viewCount'] ?? 0) / 100).clamp(0, 5);
19
20 // Personalization scoring
21 if (userCategories.contains(item['category'])) score += 3;
22
23 return score;
24}
25
26List<Map<String, dynamic>> scoreAndRankResults(
27 List<Map<String, dynamic>> items,
28 String query,
29 List<String> userCategories,
30) {
31 for (var item in items) {
32 item['_score'] = scoreItem(item, query, userCategories);
33 }
34 items.sort((a, b) => (b['_score'] as double).compareTo(a['_score'] as double));
35 return items;
36}

Expected result: A Custom Function that scores each result on multiple factors and returns the list sorted by relevance score.

3

Display ranked results with highlighted match terms

On the SearchPage, bind the ListView to the output of the scoreAndRankResults function. Each result card is a Container showing the title, description snippet, category badge, viewCount, and timestamp. For highlighting matched terms in the title and description, create a Custom Widget that takes the text and query as parameters and renders a RichText widget. The widget splits the text at query match positions and applies bold styling with a yellow background to the matched segments while keeping the rest in normal styling. This visual highlight helps users see why each result matched.

highlighted_text.dart
1// Custom Widget: HighlightedText
2import 'package:flutter/material.dart';
3
4class HighlightedText extends StatelessWidget {
5 final String text;
6 final String highlight;
7 final TextStyle baseStyle;
8
9 const HighlightedText({
10 required this.text,
11 required this.highlight,
12 this.baseStyle = const TextStyle(fontSize: 14),
13 });
14
15 @override
16 Widget build(BuildContext context) {
17 if (highlight.isEmpty) return Text(text, style: baseStyle);
18 final lower = text.toLowerCase();
19 final queryLower = highlight.toLowerCase();
20 final List<TextSpan> spans = [];
21 int start = 0;
22 int idx;
23 while ((idx = lower.indexOf(queryLower, start)) != -1) {
24 if (idx > start) spans.add(TextSpan(text: text.substring(start, idx)));
25 spans.add(TextSpan(
26 text: text.substring(idx, idx + highlight.length),
27 style: baseStyle.copyWith(
28 fontWeight: FontWeight.bold,
29 backgroundColor: Colors.yellow.withOpacity(0.3),
30 ),
31 ));
32 start = idx + highlight.length;
33 }
34 if (start < text.length) spans.add(TextSpan(text: text.substring(start)));
35 return RichText(text: TextSpan(style: baseStyle, children: spans));
36 }
37}

Expected result: Search results display in relevance order with matched query terms visually highlighted in bold with a yellow background.

4

Add Algolia integration for full-text search

For apps needing real full-text search with typo tolerance, synonyms, and faceted filtering, integrate Algolia. In FlutterFlow, go to Settings and configure the Algolia integration with your Application ID and Search API Key. Sync your Firestore collection to an Algolia index using the Firebase Extensions Algolia Search extension. On the SearchPage, switch the Backend Query to Algolia Search Query instead of Firestore. Algolia handles relevance ranking, typo tolerance (finding 'restaurnt' when searching 'restaurant'), and instant results. Configure searchable attributes in the Algolia dashboard, setting title as the primary searchable attribute and description as secondary. Add faceted filtering for category using Algolia facets.

Expected result: Algolia powers the search with instant full-text matching, typo tolerance, and server-side relevance ranking.

5

Add manual sort override and search analytics

Below the search TextField, add a DropDown for manual sort override with options: Most Relevant (default, uses the scoring algorithm), Newest First (sort by timestamp descending), Most Popular (sort by viewCount descending), and Alphabetical (sort by title ascending). When a user selects a non-relevance sort, bypass the scoring function and apply a simple sort on the selected field. Track search behavior: on each search, log the query, results count, and which result the user tapped to an analytics collection. Use this data to improve scoring weights over time. If certain queries consistently lead to clicks on lower-ranked results, adjust the factor weights.

Expected result: Users can override the relevance sort with manual options, and search analytics track behavior for continuous improvement.

Complete working example

FlutterFlow Dynamic Search Sorting Setup
1FIRESTORE DATA MODEL:
2 articles/{articleId} (or any searchable collection)
3 title: String
4 titleLowerCase: String
5 description: String
6 category: String
7 viewCount: Integer
8 tags: [String]
9 timestamp: Timestamp
10
11 search_analytics/{logId} (optional)
12 query: String
13 resultsCount: Integer
14 clickedResultId: String
15 timestamp: Timestamp
16
17APP STATE:
18 recentCategories: [String] (persisted, tracks user's viewed categories)
19
20CUSTOM FUNCTION: scoreAndRankResults(items, query, userCategories)
21 Scoring per item:
22 +10: title contains query
23 +5: title starts with query
24 +3: description contains query
25 +0-5: recency (newer = higher)
26 +0-5: popularity (viewCount / 100, capped)
27 +3: category matches user preference
28 Sort by total score descending
29
30CUSTOM WIDGET: HighlightedText(text, highlight)
31 Renders RichText with bold+yellow on matched segments
32
33PAGE: SearchPage
34WIDGET TREE:
35 Column
36 Row
37 TextField (search query)
38 IconButton (search)
39 Row
40 DropDown (sort: Relevant | Newest | Popular | A-Z)
41 Text ("X results" count)
42 ListView (ranked results)
43 Container (result card)
44 HighlightedText (title, query)
45 HighlightedText (description snippet, query)
46 Row
47 Badge (category)
48 Text (viewCount + eye icon)
49 Text (relative timestamp)
50 On Tap: Navigate + log search analytics
51
52ALGOLIA INTEGRATION (optional):
53 Settings Algolia Application ID + Search API Key
54 Sync: Firebase Extension Algolia Search
55 Searchable attributes: title (rank 1), description (rank 2)
56 Facets: category

Common mistakes when implementing a Dynamic Sorting Algorithm for Search Results in FlutterFlow

Why it's a problem: Running the scoring algorithm on all documents in the collection client-side

How to avoid: Limit the Firestore fetch to the top 100 candidates using basic filters (prefix match, category filter). Score and rank only those 100 on the client.

Why it's a problem: Using case-sensitive string matching for search queries

How to avoid: Store a lowercase version of searchable fields (titleLowerCase) and convert the query to lowercase before comparison. All matching happens in lowercase.

Why it's a problem: Not providing a fallback when Algolia is unavailable

How to avoid: Implement a fallback Firestore-based search that activates when Algolia returns an error. It won't have typo tolerance but will still return basic results.

Best practices

  • Limit candidate fetch to 100 results for client-side scoring to maintain UI responsiveness
  • Store lowercase versions of searchable fields for case-insensitive matching
  • Weight scoring factors based on what matters most to your users (text match usually highest)
  • Highlight matched terms in results so users can see why each result appeared
  • Track which results users click to validate and improve scoring weights over time
  • Provide manual sort options so power users can override the algorithm
  • Use Algolia for production apps needing typo tolerance and instant full-text search

Still stuck?

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

ChatGPT Prompt

I want to implement a dynamic search result sorting algorithm in FlutterFlow. Show me how to build a multi-factor scoring function (text match, recency, popularity, personalization), limit and rank Firestore results client-side, highlight matched terms, and optionally integrate Algolia for full-text search.

FlutterFlow Prompt

Create a search results page with a search bar at the top, a sort dropdown below it, and a list of result cards. Each card should show a title, description, category badge, and view count.

Frequently asked questions

Does Firestore support full-text search natively?

No. Firestore supports exact match, prefix match, and array-contains queries, but not fuzzy text search or typo tolerance. For full-text search, use Algolia, Typesense, or Meilisearch integrated via Cloud Functions or FlutterFlow's built-in Algolia support.

How do I handle search queries with multiple words?

Split the query into individual words and score each word match separately. A result matching all words scores higher than one matching only some. For multi-word exact phrase matching, compare the full phrase against the text.

Can I adjust scoring weights after launch?

Yes. Store scoring weights in a Firestore config document (textMatchWeight, recencyWeight, popularityWeight). Read these in the scoring function. Admins can adjust weights without code changes and see results immediately.

How do I boost certain results like featured or sponsored items?

Add a boostScore field to documents that should be promoted. In the scoring function, add this boost to the total score. Featured items will rank higher naturally without a separate promoted section.

What is the cost of Algolia for a small app?

Algolia offers a free tier with 10,000 search requests per month and 10,000 records. The Build plan starts at $0 with pay-as-you-go pricing. For most small apps, the free tier is sufficient.

Can RapidDev help implement advanced search?

Yes. RapidDev can implement full-text search with Algolia or Elasticsearch, custom ranking algorithms, AI-powered semantic search, autocomplete suggestions, faceted navigation, and search 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.