Build a post-signup onboarding flow using a PageView with 4-5 data collection steps: profile setup with avatar upload, interest selection via ChoiceChips, notification preferences with toggle switches, and a tutorial walkthrough. A LinearPercentIndicator tracks progress above the PageView. Each step saves data to Firestore immediately so users can resume after a crash. An App State onboardingComplete flag skips the flow on future launches.
Building a Multistep Onboarding Flow in FlutterFlow
A well-designed onboarding flow collects essential user data after signup without overwhelming new users with a single long form. This tutorial creates a step-by-step experience with avatar upload, interest selection, notification toggles, and a tutorial walkthrough. Each step saves immediately to Firestore, and the flow is skipped automatically for returning users.
Prerequisites
- A FlutterFlow project with Firebase Authentication set up
- Firestore database with a users collection
- Firebase Storage enabled for avatar uploads
- Basic understanding of Page State and App State in FlutterFlow
Step-by-step guide
Create the onboarding page with PageView and progress indicator
Create the onboarding page with PageView and progress indicator
Create a new page called Onboarding. Add a Column as the root. Inside, add a LinearPercentIndicator widget at the top with percent bound to a Page State variable currentStep divided by totalSteps (e.g., currentStep / 4). Below it, add a PageView with physics set to NeverScrollableScrollPhysics to prevent free swiping — navigation should only happen via the Continue button. Add 4 child pages inside the PageView. At the bottom of the Column, add a Row with a Back button (goes to previous page) and a Continue button (advances to the next page). Use Conditional Visibility to hide the Back button on step 1.
Expected result: The onboarding page shows a progress bar at the top, a PageView area for step content, and navigation buttons at the bottom. The PageView cannot be swiped freely.
Build Step 1: Profile setup with avatar and display name
Build Step 1: Profile setup with avatar and display name
In PageView child 1, add a Column with a centered CircleImage (150x150) showing a placeholder person icon. Below it, add a FlutterFlowUploadButton that lets the user pick a photo from their gallery. On upload, store the photo URL in Page State avatarUrl and update the CircleImage to show the uploaded photo. Below, add a TextField for display name bound to Page State displayName with validation requiring at least 2 characters. The Continue button on this step should check that displayName is not empty before advancing.
Expected result: Step 1 shows a circular avatar area with an upload button and a display name field. Users can upload a photo and enter their name before proceeding.
Build Step 2: Interest selection with ChoiceChips
Build Step 2: Interest selection with ChoiceChips
In PageView child 2, add a Text heading 'What are you interested in?' and a ChoiceChips widget with options from an Option Set (e.g., Technology, Design, Business, Health, Education, Entertainment). Set allowMultipleSelection to true. Bind the selected values to Page State selectedInterests (List of Strings). Add a minimum selection validation on the Continue button: check that selectedInterests has at least 1 item before advancing. Display a helper text 'Select at least 1 topic' below the ChoiceChips.
Expected result: Step 2 presents interest categories as selectable chips. Users can pick one or more interests, and the Continue button validates at least one is selected.
Build Steps 3-4: Notification preferences and tutorial walkthrough
Build Steps 3-4: Notification preferences and tutorial walkthrough
In PageView child 3, add toggle Switches for notification preferences: Push Notifications, Email Updates, and Weekly Digest. Bind each to a Page State boolean. In PageView child 4, create a tutorial screen with an illustration Image, a heading 'You are all set!', a brief description of what the app offers, and a 'Get Started' button instead of Continue. This final step does not need validation since all data has been collected in prior steps.
Expected result: Step 3 shows notification toggle switches with sensible defaults. Step 4 shows a welcome screen with a Get Started button to complete onboarding.
Save partial progress on each step to Firestore
Save partial progress on each step to Firestore
On each Continue button tap, before advancing the PageView, add an Update Document action that writes the current step's data to the user document. Step 1 saves avatarUrl and displayName. Step 2 saves selectedInterests. Step 3 saves notificationPreferences. Also update an onboardingStep integer field on the user doc to track which step was last completed. On the Onboarding page load, read the user's onboardingStep and animate the PageView to that step so returning users resume where they left off.
Expected result: Each step's data is saved immediately to Firestore. If the app crashes or the user leaves, they resume from the last completed step on their next visit.
Skip onboarding for returning users with App State flag
Skip onboarding for returning users with App State flag
Add a persisted App State variable onboardingComplete (Boolean, default false). On the Get Started button tap in Step 4, update the user document with onboardingComplete: true and set the App State onboardingComplete to true, then Navigate to the Home page using Replace Route so the user cannot go back. In your app's initial routing logic (e.g., on the Splash or Auth page), add a Conditional Action: if the user is authenticated AND App State onboardingComplete is true, navigate directly to Home. If authenticated but onboardingComplete is false, navigate to Onboarding.
Expected result: New users are routed to the onboarding flow after signup. Returning users who completed onboarding go directly to the home page.
Complete working example
1// Onboarding Page — Action Flow Summary23// PAGE LOAD:4// 1. Backend Query: Get current user document5// 2. IF user.onboardingComplete == true → Navigate to Home (Replace Route)6// 3. ELSE IF user.onboardingStep > 0 → Animate PageView to user.onboardingStep7// 4. Set Page State: currentStep = user.onboardingStep ?? 089// STEP 1 — CONTINUE BUTTON:10// 1. Validate: displayName.length >= 211// 2. IF invalid → Show SnackBar 'Please enter your name'12// 3. ELSE:13// a. Update Document: users/{uid} → { displayName, avatarUrl, onboardingStep: 1 }14// b. Set Page State: currentStep = 115// c. Animate PageView to page 11617// STEP 2 — CONTINUE BUTTON:18// 1. Validate: selectedInterests.length >= 119// 2. IF invalid → Show SnackBar 'Select at least 1 interest'20// 3. ELSE:21// a. Update Document: users/{uid} → { interests: selectedInterests, onboardingStep: 2 }22// b. Set Page State: currentStep = 223// c. Animate PageView to page 22425// STEP 3 — CONTINUE BUTTON:26// 1. Update Document: users/{uid} → {27// pushNotifications: pushToggle,28// emailUpdates: emailToggle,29// weeklyDigest: digestToggle,30// onboardingStep: 331// }32// 2. Set Page State: currentStep = 333// 3. Animate PageView to page 33435// STEP 4 — GET STARTED BUTTON:36// 1. Update Document: users/{uid} → { onboardingComplete: true }37// 2. Set App State: onboardingComplete = true38// 3. Navigate to Home (Replace Route)3940// BACK BUTTON (visible on steps 1-3):41// 1. Set Page State: currentStep = currentStep - 142// 2. Animate PageView to previous pageCommon mistakes
Why it's a problem: Not saving partial progress between steps
How to avoid: Save each step's data to Firestore immediately on Continue and track the onboardingStep integer so users resume from where they left off.
Why it's a problem: Using Page State for the onboardingComplete flag instead of persisted App State
How to avoid: Use a persisted App State variable for onboardingComplete and also write it to the Firestore user document for cross-device persistence.
Why it's a problem: Allowing PageView swiping without field validation
How to avoid: Set the PageView physics to NeverScrollableScrollPhysics and control advancement only through the Continue button, which validates required fields before proceeding.
Best practices
- Keep onboarding to 3-5 steps maximum — every additional step increases drop-off by roughly 10%
- Show the progress indicator prominently so users know how many steps remain
- Pre-fill fields from authentication data (e.g., display name from Google OAuth) to reduce friction
- Make avatar upload optional with a default placeholder so users are not blocked
- Use Replace Route when navigating to Home after onboarding so the back button does not return to onboarding
- Test the resume flow by killing the app mid-onboarding and verifying it picks up at the correct step
- Add skip functionality for non-essential steps like interest selection to reduce abandonment
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I need to build a multistep onboarding flow in FlutterFlow with 4 steps: profile setup, interest selection, notification preferences, and a welcome screen. Show me how to structure the PageView, save progress per step, and skip onboarding for returning users using App State.
Create an onboarding page with a PageView containing 4 steps: avatar upload + name, ChoiceChips for interests, notification toggle switches, and a welcome screen. Add a progress bar at the top and Continue/Back buttons at the bottom.
Frequently asked questions
Can I add or remove onboarding steps later without breaking existing users?
Yes. Check the onboardingStep field against the new total steps count. If a returning user's step exceeds the new total, treat them as complete. If new steps were added after their last step, route them to the new steps only.
How do I handle onboarding across multiple devices?
Store onboardingComplete and onboardingStep in the Firestore user document rather than relying solely on local App State. On each device, read these fields from Firestore on login to determine the correct state.
Should I allow users to skip the entire onboarding?
It depends on your app. If display name is required for the app to function, make step 1 mandatory. For preference steps, adding a Skip button reduces friction but may lower engagement. A good compromise is making profile essential and preferences optional.
How can I personalize the home page based on onboarding selections?
Use the interests array stored on the user document to filter Backend Queries on the home page. For example, query content where category is in the user's selectedInterests array.
Can I add animations between onboarding steps?
Yes. Use the PageView's built-in page transition animation. You can also add Lottie animations on each step page for visual polish by placing a Lottie Animation widget above the step content.
Can RapidDev help build a custom onboarding experience?
Yes. RapidDev can design and implement a branded onboarding flow with conditional branching, A/B testing different step orders, and analytics to measure completion rates at each step.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation