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

How to Create an Interactive Quiz Platform with Leaderboard in FlutterFlow

Build a full quiz platform with timed questions using PageView navigation, RadioButton answer selection, and a countdown timer. Scores are calculated and validated server-side via a Cloud Function that compares submitted answers against correct answers stored in Firestore. A leaderboard page queries quiz_results ordered by score descending and time taken ascending, displaying ranked entries with gold, silver, and bronze styling for the top three players.

What you'll learn

  • How to build a timed quiz flow with PageView and a countdown timer
  • How to validate and calculate scores server-side with a Cloud Function
  • How to display a ranked leaderboard with time-based tiebreaking
  • How to store and query quiz results in Firestore for competitive play
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner8 min read30-40 minFlutterFlow Free+March 2026RapidDev Engineering Team
TL;DR

Build a full quiz platform with timed questions using PageView navigation, RadioButton answer selection, and a countdown timer. Scores are calculated and validated server-side via a Cloud Function that compares submitted answers against correct answers stored in Firestore. A leaderboard page queries quiz_results ordered by score descending and time taken ascending, displaying ranked entries with gold, silver, and bronze styling for the top three players.

Building a Competitive Quiz Platform in FlutterFlow

This tutorial walks you through creating a quiz platform where users answer timed multiple-choice questions and compete on a leaderboard. Unlike a simple quiz widget, this is a full platform with multiple quizzes, server-validated scoring to prevent cheating, and a ranked leaderboard that breaks ties by time taken. It is ideal for e-learning apps, trivia games, and employee training tools.

Prerequisites

  • A FlutterFlow project with Firestore configured
  • Basic understanding of PageView and Component State in FlutterFlow
  • A Firebase project with Cloud Functions enabled (Blaze plan)
  • Familiarity with creating Firestore collections and documents

Step-by-step guide

1

Set up the Firestore data model for quizzes, questions, and results

Create a quizzes collection with fields: title (String), description (String), category (String), questionCount (int), timeLimit (int, seconds). Under each quiz document, create a questions subcollection with fields: questionText (String), options (String array of 4 items), correctIndex (int, 0-3), order (int). Create a top-level quiz_results collection with fields: userId (String), quizId (String), score (int), totalQuestions (int), timeTaken (int, seconds), completedAt (Timestamp). Add 5-10 test questions for at least one quiz.

Expected result: Firestore has quizzes with a questions subcollection and a quiz_results collection ready for score storage.

2

Build the quiz page with timed PageView navigation

Create a QuizPage with Route Parameter quizId (String). Add a Backend Query for the questions subcollection ordered by order ascending. Add Component State: currentIndex (int, default 0), selectedAnswerIndex (int, default -1), selectedAnswers (int List, empty), startTime (Timestamp, set on page load). Place a Row at the top with a LinearPercentIndicator for question progress and a Text widget showing the countdown timer. Use a Periodic Action (every 1 second) that decrements the remaining time from the quiz timeLimit. Below, add a PageView with NeverScrollableScrollPhysics containing one question per page.

Expected result: A quiz page loads questions from Firestore with a visible countdown timer and progress bar.

3

Display questions with RadioButton answer selection

Inside each PageView page, add a Column with the questionText in Headline Small style, a SizedBox for spacing, and a RadioButton group bound to the options array. When the user taps an option, update Component State selectedAnswerIndex. Below the options, add a Next button that is disabled when selectedAnswerIndex equals -1. On Next tap: append selectedAnswerIndex to the selectedAnswers list, reset selectedAnswerIndex to -1, increment currentIndex, and call Animate to Next Page. On the last question, change button text to Submit.

Expected result: Each question displays with four selectable options, and the Next button advances through questions one at a time.

4

Calculate and validate the score via a Cloud Function

Create a Cloud Function called calculateQuizScore that accepts userId, quizId, and selectedAnswers array. The function reads the questions subcollection server-side, compares each submitted answer to the correctIndex, tallies the score, calculates timeTaken from startTime to now, and writes a quiz_results document with userId, quizId, score, totalQuestions, timeTaken, and completedAt. On the Submit button tap in FlutterFlow, call this Cloud Function via an API Call action, passing the Component State data. This prevents client-side score manipulation.

calculateQuizScore.js
1// Cloud Function: calculateQuizScore
2const functions = require('firebase-functions');
3const admin = require('firebase-admin');
4admin.initializeApp();
5
6exports.calculateQuizScore = functions.https.onCall(async (data, context) => {
7 const { quizId, selectedAnswers } = data;
8 const userId = context.auth.uid;
9 const questionsSnap = await admin.firestore()
10 .collection('quizzes').doc(quizId)
11 .collection('questions').orderBy('order').get();
12
13 let score = 0;
14 questionsSnap.docs.forEach((doc, i) => {
15 if (doc.data().correctIndex === selectedAnswers[i]) score++;
16 });
17
18 const result = {
19 userId,
20 quizId,
21 score,
22 totalQuestions: questionsSnap.size,
23 timeTaken: Math.floor((Date.now() - data.startTime) / 1000),
24 completedAt: admin.firestore.FieldValue.serverTimestamp(),
25 };
26 await admin.firestore().collection('quiz_results').add(result);
27 return result;
28});

Expected result: Score is calculated server-side and saved to quiz_results, preventing any client-side cheating.

5

Display the results page with score breakdown

After the Cloud Function returns, navigate to a ResultsPage passing score, totalQuestions, and timeTaken as Route Parameters. Display a CircularPercentIndicator showing the percentage score, a Text with the fraction (e.g., 8 out of 10), and the time taken. Add a Lottie animation for celebration if score is above 70 percent, or encouragement if below. Include a Retake Quiz button that navigates back to QuizPage and a View Leaderboard button.

Expected result: A results screen shows the score with visual feedback, time taken, and navigation options.

6

Build the leaderboard page with ranked entries

Create a LeaderboardPage with Route Parameter quizId. Add a Backend Query on quiz_results filtered by quizId, ordered by score descending then timeTaken ascending (Firestore composite index required). Display the top 3 entries in a special Row with gold, silver, and bronze Container styling using CircleImage avatars and score Text. Below, show remaining entries in a ListView with rank numbers, display names, scores, and time taken. Highlight the current user's row with a distinct background color. Add ChoiceChips for filtering by Today, This Week, or All Time using completedAt date ranges.

Expected result: A ranked leaderboard displays quiz results with the top three highlighted and the current user's position visible.

Complete working example

FlutterFlow Quiz Platform Setup
1FIRESTORE DATA MODEL:
2 quizzes/{quizId}
3 title: String
4 description: String
5 category: String
6 questionCount: int
7 timeLimit: int (seconds)
8 questions/{questionId}
9 questionText: String
10 options: ["A", "B", "C", "D"]
11 correctIndex: int (0-3)
12 order: int
13
14 quiz_results/{resultId}
15 userId: String
16 quizId: String
17 score: int
18 totalQuestions: int
19 timeTaken: int (seconds)
20 completedAt: Timestamp
21
22PAGE: QuizPage
23 Route Parameter: quizId (String)
24 Backend Query: questions subcollection, order by order asc
25 Periodic Action: every 1s, decrement timer
26
27COMPONENT STATE:
28 currentIndex: int = 0
29 selectedAnswerIndex: int = -1
30 selectedAnswers: List<int> = []
31 remainingSeconds: int = quiz.timeLimit
32 startTime: int = DateTime.now().millisecondsSinceEpoch
33
34WIDGET TREE (QuizPage):
35 Column
36 Row
37 LinearPercentIndicator (currentIndex / totalQuestions)
38 Text (remainingSeconds formatted as mm:ss)
39 PageView (NeverScrollableScrollPhysics)
40 Per question:
41 Column
42 Text (questionText, Headline Small)
43 RadioButtonGroup (options, selectedAnswerIndex)
44 Button ("Next" / "Submit")
45 On Tap: append answer next page or call Cloud Function
46
47PAGE: ResultsPage
48 Route Params: score, totalQuestions, timeTaken
49 Column
50 CircularPercentIndicator (score / totalQuestions)
51 Text ("score out of totalQuestions")
52 Text (timeTaken formatted)
53 Lottie (celebration or try-again)
54 Button ("Retake Quiz")
55 Button ("View Leaderboard")
56
57PAGE: LeaderboardPage
58 Route Parameter: quizId
59 Backend Query: quiz_results where quizId, orderBy score desc + timeTaken asc
60 Column
61 Row (Top 3: gold / silver / bronze cards)
62 ChoiceChips (Today / Week / All Time)
63 ListView (remaining entries with rank + avatar + score + time)

Common mistakes when creating an Interactive Quiz Platform with Leaderboard in FlutterFlow

Why it's a problem: Calculating the score on the client and trusting the result

How to avoid: Send only the selectedAnswers array to a Cloud Function. The function reads correct answers server-side and calculates the score itself.

Why it's a problem: Using App State for quiz answers instead of Component State

How to avoid: Use Component State or Page State for in-progress quiz data. These reset when the page is left.

Why it's a problem: Not creating the Firestore composite index for leaderboard queries

How to avoid: Create a composite index on quiz_results: quizId (ascending), score (descending), timeTaken (ascending) in the Firebase Console.

Why it's a problem: Allowing users to swipe between PageView questions freely

How to avoid: Set PageView physics to NeverScrollableScrollPhysics so navigation only occurs via the Next button.

Best practices

  • Validate scores server-side in a Cloud Function to prevent cheating
  • Use NeverScrollableScrollPhysics on the PageView to enforce sequential question flow
  • Show a countdown timer and auto-submit when time expires
  • Store quiz results with timeTaken for meaningful leaderboard tiebreaking
  • Display the current user's rank even if they are not in the top entries
  • Disable the Next button until an answer is selected to prevent blank submissions
  • Create Firestore composite indexes proactively for leaderboard sort queries

Still stuck?

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

ChatGPT Prompt

I want to build a quiz platform in FlutterFlow with timed multiple-choice questions using PageView, server-side score validation via Cloud Functions, and a ranked leaderboard that breaks ties by time taken. Give me the Firestore data model, widget tree, action flows, and Cloud Function code.

FlutterFlow Prompt

Create a quiz page with a timer at the top right, a progress bar below it, a large question text in the center, four radio button answer options, and a Next button at the bottom. Add a leaderboard page with a top-3 podium section and a ranked list below.

Frequently asked questions

Can I randomize the question order for each quiz attempt?

Firestore does not support random ordering in queries. Fetch all questions, shuffle the list in a Custom Function before binding to the PageView, and use the shuffled list for display and answer tracking.

How do I prevent users from retaking a quiz?

On page load, query quiz_results for the current userId and quizId. If a document exists, redirect to the results page showing their previous score instead of starting the quiz.

Can I add different difficulty levels to quizzes?

Yes. Add a difficulty field to each quiz document. On the quiz catalog page, use ChoiceChips to filter quizzes by difficulty. You can also weight scoring by difficulty in the Cloud Function.

How do I show which answers were correct after submission?

On the results page, display each question with the user's selected answer and the correct answer. Use Conditional Styling to color correct answers green and incorrect ones red.

What happens if the timer runs out mid-quiz?

Set up the Periodic Action to check when remainingSeconds reaches zero. When it does, auto-submit whatever answers have been collected so far by calling the Cloud Function with the partial selectedAnswers array.

Can RapidDev help build a full quiz and e-learning platform?

Yes. RapidDev can build complete quiz platforms with adaptive difficulty, certificate generation, analytics dashboards, and multi-format question types beyond multiple choice.

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.