Empty or incorrect query results in FlutterFlow are almost always caused by one of four things: a misconfigured Backend Query (wrong collection path, case-sensitive field name typo, or mismatched filter operator), a missing composite index in Firestore, a Supabase Row Level Security policy blocking the read, or a Test Mode auth context that bypasses the rules that apply to real users in production. Debug each layer in order — query config first, then index errors, then auth and RLS.
Why your FlutterFlow query returns nothing — and how to find out
A Backend Query that silently returns zero results is one of the most frustrating problems in FlutterFlow development. The UI just shows an empty list with no error message, leaving you no indication of where the problem is. The root cause is almost always one of four places: the query configuration in FlutterFlow (wrong path, bad field name, wrong operator), a Firestore index that does not exist yet, a Supabase RLS policy that is blocking the authenticated user, or a false positive from Test Mode that masks the real-world behavior.
This tutorial gives you a systematic debugging checklist for both Firestore and Supabase backends. You will learn to verify each layer of the query stack in order — from the Backend Query widget settings in FlutterFlow, to the Firebase Console query builder, to the Supabase SQL Editor — and understand exactly why each mistake causes silent failures rather than visible errors.
Prerequisites
- A FlutterFlow project connected to either Firestore or Supabase with at least one Backend Query already configured
- Access to the Firebase Console (console.firebase.google.com) or Supabase Dashboard (app.supabase.com) for your project
- Basic understanding of FlutterFlow's Backend Query widget and how to attach it to a page or widget
- A test user account in your app to use during Run mode testing on a physical device or emulator
Step-by-step guide
Audit your Backend Query configuration in FlutterFlow
Audit your Backend Query configuration in FlutterFlow
Open the page or widget that has the failing Backend Query. Click the Backend Query icon (the database cylinder icon) on the widget or page to open the query editor. Go through each field systematically: 1. Collection path: Firestore paths are case-sensitive. 'Users' and 'users' are different collections. If your Firestore collection is named 'orders', the path in FlutterFlow must be exactly 'orders' — not 'Orders' or 'order'. For subcollections, the path must alternate document and collection: 'users/{userId}/orders'. 2. Filter field names: Every field name in your filter conditions must exactly match the field name in Firestore or Supabase — including capitalization. Open Firebase Console → Firestore → your collection → any document and read the field names directly. Compare them character-by-character to what you typed in FlutterFlow. 3. Filter operators: Confirm you are using the correct operator for the data type. Using 'Equal To' on a Timestamp field when the stored value includes milliseconds will never match. Use 'Less Than or Equal To' with end-of-day timestamp for date range queries. 4. Order By field: If you have an Order By set, confirm the field exists on every document in the collection. A single document missing that field can cause the entire query to return nothing in some configurations.
Expected result: You have verified collection path, field names, filter operators, and ordering settings are all correctly configured.
Reproduce the query in Firebase Console to isolate FlutterFlow
Reproduce the query in Firebase Console to isolate FlutterFlow
The fastest way to determine whether your query logic is correct is to run it directly in the Firebase Console, bypassing FlutterFlow entirely. Open Firebase Console → Firestore Database → Data tab → navigate to your collection. Click the Filter icon in the top-right of the collection view. Add the same filter conditions you have in your FlutterFlow Backend Query — same field, same operator, same value. Click Apply. If the Firebase Console filter returns documents, the query logic is correct and the problem is in FlutterFlow's configuration or auth context. If the Firebase Console filter also returns zero results, the problem is in your data or query logic itself — not FlutterFlow. For inequality filters combined with orderBy: Firestore requires that when you use a filter like 'status != completed' or 'price > 100', the first orderBy field must match the inequality filter field. If you orderBy 'createdAt' but filter on 'price > 100', Firestore rejects the query. In Firebase Console you will see the error message that FlutterFlow hides.
Expected result: You have confirmed whether the query returns data in Firebase Console, narrowing the problem to either query logic or FlutterFlow configuration.
Check for missing Firestore composite indexes
Check for missing Firestore composite indexes
When a Firestore query combines a filter on one field with an orderBy on a different field, Firestore requires a composite index — it cannot run this query without one. FlutterFlow does not surface the resulting error to the UI; the query simply returns nothing. To find missing index errors: open Firebase Console → Firestore Database → Indexes tab. Look for any indexes with a 'Building' or 'Error' status. Alternatively, open Firebase Console → Firestore Database → Usage → Log entries and look for error messages containing 'FAILED_PRECONDITION' or 'The query requires an index'. The error message in the logs will include a direct URL to create the exact index you need — copy that URL into your browser and click 'Create Index'. Index creation takes 2-10 minutes depending on collection size. Three query patterns that always require composite indexes in Firestore: - Filter on field A + orderBy on field B (different fields) - Filter with inequality (!=, <, >, <=, >=) + any orderBy - Two or more inequality filters on different fields (not supported at all — requires restructuring) For arrayContains queries: the arrayContains operator only works on fields that actually store an array type. If the field stores a string or number, arrayContains always returns zero results without an error.
Expected result: Any missing composite indexes are identified and created in Firebase Console, and arrayContains fields are confirmed to store array-type values.
Test Supabase queries in the SQL Editor and verify RLS policies
Test Supabase queries in the SQL Editor and verify RLS policies
For Supabase backends, open your Supabase Dashboard → SQL Editor. Write a direct SELECT query matching your FlutterFlow query: SELECT * FROM your_table WHERE your_filter_column = 'your_value' ORDER BY created_at DESC LIMIT 20; If this query returns rows in the SQL Editor, the data exists and the logic is correct. The SQL Editor runs as the Postgres service role, which bypasses Row Level Security. To test what a real authenticated user would see, run: SET LOCAL ROLE authenticated; SET LOCAL request.jwt.claims = '{"sub": "YOUR_USER_UUID"}'; SELECT * FROM your_table WHERE your_filter_column = 'your_value'; If this returns fewer rows or zero rows, an RLS policy is blocking the read. Go to Authentication → Policies and review the SELECT policy on your table. Common RLS mistakes that cause silent query failures: 1. RLS is enabled but no SELECT policy exists — all reads are blocked for authenticated users 2. The SELECT policy uses auth.uid() = user_id but the user_id column stores the email instead of the UUID 3. The policy has a typo in the column name — Supabase silently treats it as a null comparison 4. Multiple conflicting policies — one permissive policy and one restrictive policy interact unexpectedly In FlutterFlow's Supabase Backend Query editor, confirm the Filter Row field names exactly match the Supabase column names (case-sensitive).
1-- Test query as service role (bypasses RLS) — paste in Supabase SQL Editor2SELECT * FROM orders3WHERE status = 'active'4ORDER BY created_at DESC5LIMIT 20;67-- Test the same query as an authenticated user8-- Replace YOUR_USER_UUID with an actual user's UUID from auth.users table9SET LOCAL ROLE authenticated;10SET LOCAL "request.jwt.claims" = '{"sub": "YOUR_USER_UUID", "role": "authenticated"}';1112SELECT * FROM orders13WHERE status = 'active'14ORDER BY created_at DESC15LIMIT 20;1617-- Check which RLS policies exist on the table18SELECT schemaname, tablename, policyname, permissive, roles, cmd, qual19FROM pg_policies20WHERE tablename = 'orders';2122-- Check if RLS is enabled on the table23SELECT relname, relrowsecurity24FROM pg_class25WHERE relname = 'orders';Expected result: You have confirmed whether the query returns data in SQL Editor, identified any RLS policy blocking authenticated user reads, and verified column names match exactly.
Enable debug output in FlutterFlow and run on a physical device
Enable debug output in FlutterFlow and run on a physical device
FlutterFlow's Test Mode (the browser preview) runs in a different environment than the deployed app — it may use a different auth token, different security context, or bypass certain Firebase Security Rules checks. Never conclude a query is working based solely on Test Mode results. To test with real auth context: 1. In FlutterFlow, click the Run button (triangle icon, top-right) instead of the Test button 2. Select your target platform (iOS or Android) 3. FlutterFlow will build and push to your connected physical device or emulator 4. Log in with a real test user account — not the FlutterFlow preview account 5. Navigate to the page with the failing query and observe whether data appears For additional visibility, add a temporary debug display to your page: - Add a Text widget outside the query-bound widget tree - Bind it to a Page State variable named debugInfo (String) - In the Backend Query's On Completed action: Update Page State → debugInfo → set to 'Query complete. Count: ' + query_result_count - In the On Error action: Update Page State → debugInfo → 'Error: ' + error_message This makes invisible failures visible. Remove these debug widgets before publishing.
Expected result: You have confirmed query behavior with a real authenticated user in Run mode on a physical device, with debug text displaying the actual result count or error message.
Fix the identified issue and verify the complete query flow
Fix the identified issue and verify the complete query flow
Apply the fix for whichever issue you identified in the previous steps: For collection path or field name errors: correct the typo in the Backend Query editor. Remember to check every filter condition — if you have three filters, all three field names must be verified. For missing Firestore indexes: wait for the index to finish building (Firebase Console → Indexes → status turns green). Then re-run your query. Indexes that are still building return zero results without an error. For RLS policy issues in Supabase: update or create the SELECT policy in Authentication → Policies. The simplest correct policy for user-owned data is: (auth.uid() = user_id) where user_id is the UUID column linking rows to the authenticated user. For inequality + orderBy conflicts: restructure the query to add orderBy on the filter field first, then add secondary orderBy fields. After applying the fix: 1. Test in Firebase Console or Supabase SQL Editor — confirm data returns 2. Run on physical device with your test account — confirm the UI populates 3. Test with a second user account that should NOT see the data — confirm it is empty for them 4. Remove all debug Text widgets and Page State debug variables before publishing
Expected result: The Backend Query returns the correct data for authenticated users in Run mode, returns empty for unauthorized users, and the debug widgets have been removed.
Complete working example
1QUERY DEBUG CHECKLIST — work through each section in order23─────────────────────────────────────────────41. BACKEND QUERY CONFIG (FlutterFlow editor)5─────────────────────────────────────────────6□ Collection path matches exactly (case-sensitive)7 Firestore: 'orders' not 'Orders'8 Supabase: 'orders' not 'Orders'910□ Filter field names match document/column names exactly11 Open Firebase Console or Supabase Table Editor12 Copy-paste field names — do not retype1314□ Filter operator is correct for data type15 String → Equal To / Contains16 Number → Equal To / Greater Than / Less Than17 Timestamp → use Less Than or Equal To for date ranges18 Array → Array Contains (field must store an actual array)1920□ Order By field exists on EVERY document in the collection21 A single doc missing the field can cause full query failure2223─────────────────────────────────────────────242. FIRESTORE COMPOSITE INDEXES25─────────────────────────────────────────────26□ Filter field A + orderBy field B → composite index required27□ Inequality filter (!=, <, >, <=, >=) + any orderBy → composite index required28□ Check: Firebase Console → Firestore → Indexes tab29□ Look for FAILED_PRECONDITION in Firebase Console → Usage → Logs30□ Index URL in error log → click it → Create Index → wait 2-10 min3132INEQUALITY + ORDER BY RULE:33 orderBy must start with the inequality filter field34 WRONG: filter price > 100 + orderBy createdAt35 RIGHT: filter price > 100 + orderBy price, createdAt3637─────────────────────────────────────────────383. SUPABASE RLS CHECK39─────────────────────────────────────────────40□ Run query in SQL Editor as service role → does it return rows?41□ Run query as authenticated user (SET LOCAL ROLE) → same results?42□ Check pg_policies → does a SELECT policy exist for this table?43□ Policy uses correct column for auth.uid() comparison?44 auth.uid() = user_id (UUID column, not email)45□ No typos in policy column names?4647COMMON RLS FAILURES:48 - RLS enabled, no SELECT policy = all reads blocked silently49 - Policy checks wrong column = returns empty for all users50 - Conflicting permissive + restrictive policies = unpredictable5152─────────────────────────────────────────────534. AUTH CONTEXT — TEST MODE vs RUN MODE54─────────────────────────────────────────────55□ Test Mode (browser) != production auth context56□ ALWAYS verify with Run mode on physical device57□ Log in as real test user (not FlutterFlow preview account)58□ Add debug Text widget showing query result count59□ Confirm empty results for users who should NOT see data60□ REMOVE debug widgets before publishing6162─────────────────────────────────────────────635. QUICK DIAGNOSIS: RESULT COUNT TEXT WIDGET64─────────────────────────────────────────────65Page State variable: debugInfo (String)66Backend Query → On Completed action:67 Update Page State → debugInfo68 = 'Count: ' + [query result count]69Backend Query → On Error action:70 Update Page State → debugInfo71 = 'Error: ' + [error message]72Text widget bound to: Page State → debugInfo73(Remove before publishing)Common mistakes when debugging FlutterFlow Database Queries (Firestore & Supabase)
Why it's a problem: Assuming the query works because data appears in FlutterFlow Test Mode
How to avoid: Always validate queries by clicking Run (not Test) and deploying to a physical device or emulator. Log in with a real user account that has the same permissions as your target audience. Test Mode is only reliable for UI layout checks — treat query behavior as unconfirmed until verified in Run mode.
Why it's a problem: Typing filter field names from memory instead of copying them from the database
How to avoid: Open Firebase Console → Firestore → navigate to your collection → click any document and read the field names directly from the document view. For Supabase, open the Table Editor and read column names from the header row. Copy-paste them into FlutterFlow's filter field boxes rather than retyping.
Why it's a problem: Using a filter with inequality and orderBy on different fields without a composite index
How to avoid: Check Firebase Console → Firestore → Indexes tab for building or failed indexes. In the Firebase Console logs look for FAILED_PRECONDITION errors — they include a direct link to create the exact composite index needed. After creating the index, wait for the status to turn green (2-10 minutes) before testing again.
Best practices
- Always verify query field names by reading them directly from Firebase Console or Supabase Table Editor — never type them from memory
- Add a temporary debug Text widget bound to the query result count during development so you can see 0 vs null vs a real count
- Create composite indexes proactively when you know you will combine filters and ordering on different fields — do not wait for silent failures in production
- Test every query with at least two user accounts: one that should see data and one that should not — to confirm both the positive and negative cases
- In Supabase, use the SQL Editor to run the exact query as an authenticated user with SET LOCAL ROLE before assuming an RLS policy is correct
- For arrayContains filters, verify in Firebase Console that the target documents actually store the field as an array type — a string field with arrayContains always returns empty with no error
- Never conclude a query is production-ready based on Test Mode alone — always run on a physical device with a real user account before publishing
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I am building a FlutterFlow app using [Firestore / Supabase] as my backend. My Backend Query is returning zero results when I expect data. Here is my query configuration: collection [collection_name], filter field [field_name] [operator] [value], orderBy [field_name]. The data definitely exists in the database. Help me identify the most likely causes of a silent empty result for this query — including index requirements, field name case sensitivity, auth context differences between Test Mode and Run mode, and any operator restrictions I might be hitting.
My Backend Query on the [page name] page is returning zero results. The collection is [collection_name] and I am filtering on [field_name] equal to [value]. Can you check if there are any configuration issues with the query — wrong field names, missing indexes, or filter operator problems? Also tell me how to add a debug text widget to display the query result count so I can see what is happening.
Frequently asked questions
Why does my Backend Query work in Test Mode but return nothing on a real device?
Test Mode uses a browser-based preview with its own auth context that may have elevated permissions or bypass certain Security Rules checks. When you switch to Run mode on a real device and log in with a real user account, that user's UID is subject to your Firestore Security Rules or Supabase RLS policies. The most common cause is an RLS policy or Security Rule that correctly restricts data to its owner — in Test Mode the preview bypasses this, but real users are blocked. Always test queries in Run mode with a real account.
My Firestore query has a filter and an orderBy — why does it return zero results?
When you combine a filter on one field with an orderBy on a different field, Firestore requires a composite index. Without it, the query silently returns nothing. Go to Firebase Console → Firestore → Indexes tab and check for missing or building indexes. Also check the Usage → Logs tab for a FAILED_PRECONDITION error that includes a direct URL to create the exact index you need. After creating the index, wait for the green 'Enabled' status before testing again — index building takes 2-10 minutes.
How do I check what data a specific authenticated user can actually see in Supabase?
Open Supabase Dashboard → SQL Editor and run: SET LOCAL ROLE authenticated; SET LOCAL "request.jwt.claims" = '{"sub": "USER_UUID_HERE", "role": "authenticated"}'; SELECT * FROM your_table; Replace USER_UUID_HERE with the actual UUID from the auth.users table. This simulates the exact RLS context for that user. If this returns fewer rows than running without the SET LOCAL commands, an RLS policy is restricting their access. Check Authentication → Policies for your table to see the SELECT policy conditions.
My arrayContains filter returns zero results even though the array field has matching values
There are two common causes. First, confirm the field is actually stored as an array type in Firestore — open Firebase Console → the document → look at the field value. An array field shows a list icon, not a plain string. If it was created as a string like 'tag1,tag2', arrayContains will never match. Second, confirm the value you are searching for is an exact match including type — arrayContains on a string array with a number value returns nothing. The search value type must match the array element type exactly.
How can I see the actual error from a failed Backend Query in FlutterFlow?
FlutterFlow does not show database query errors in the UI by default — it just shows an empty list. To capture the error: open the Backend Query settings for your widget or page, scroll to the Action Flow section, and add an On Error action. Add an Alert Dialog or Update Page State action to display the error message. In Run mode on your device, trigger the query and the error message will appear. For Firestore errors, you can also check Firebase Console → Firestore → Usage → Logs filtered to Error severity.
My Supabase query returns data in the SQL Editor but not in FlutterFlow — what is wrong?
The SQL Editor runs as the Postgres service role which bypasses RLS entirely. If data appears in the SQL Editor but not in FlutterFlow, an RLS policy is almost certainly blocking the authenticated user. Run the query again with SET LOCAL ROLE authenticated and your test user's UUID as shown in Step 4. Also check that FlutterFlow's Backend Query filter column names exactly match the Supabase column names — including underscores and capitalization. A single character difference causes a silent empty result.
Can RapidDev help me set up correct Firestore indexes and RLS policies for my FlutterFlow app?
Yes. Correctly designing Firestore index strategies for complex queries and writing Supabase RLS policies that enforce proper data access without blocking legitimate reads are two of the most technically demanding parts of a FlutterFlow project. If your queries are returning inconsistent results or you are building an app where data privacy between users is critical, RapidDev can audit your database configuration and fix both the query setup and the security layer.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation