You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I give permission for members of the FlutterFlow team to access and test my project for the sole purpose of investigating this issue.
Current Behavior
FlutterFlow Bug Report — Conditional widgets in a Row render the wrong branch
Project: ZhenilKey (formerly "EasyKey"), project ID easy-key-ehowpz
Component: BookingPlaceItem (custom component, used as a list item inside a ListView on the "My Bookings" page)
Generated file: booking_place_item_widget.dart (as shown in FlutterFlow's Developer Menu → View Code)
Builder mode: Widget Tree / Test Mode (legacy Test Mode, fresh from-scratch compiles — not Instant Reload)
Summary of the bug
Inside BookingPlaceItem, a single Row contains two buttons that are each meant to appear only for one specific booking status:
Button ("Cancel Booking") — should render only when status == upcoming
ButtonRecordVideoCheckout ("Record Checkout Video") — should render only when status == ongoing
For a real Firestore booking document whose status field is "ongoing", the wrong button renders (the "Cancel Booking" button, which is gated on upcoming), and the correct button (ButtonRecordVideoCheckout, gated on ongoing) does not render — an empty gap appears in its place instead.
This happens even though:
The document's status field is genuinely "ongoing" (confirmed multiple ways, see §2).
The visibility conditions on both buttons, read directly from the widget tree / generated code, are correct and mutually exclusive (see §4).
The bug reproduces identically after replacing the conditional-rendering implementation with a structurally different FlutterFlow construct (see §3, item 4).
Confirmation that the underlying data is correct
Three temporary debug Text widgets were added inside the exact same Row/card as the two buttons, bound directly to the same component parameter (bookingRefDoc) that the button conditions use: bookingRefDoc.status.name → prints "ongoing" bookingRefDoc.status == Booking.ongoing (boolean) → prints "true"
A custom debug function getBookingIsOngoingDebug → prints "ongoing"
All three debug texts render inside the same bordered card as the misbehaving buttons (confirmed via a tight, zoomed screenshot of the single card), so there is no ambiguity about which list item/card is being inspected. The real, live status is unambiguously "ongoing" for the card that nonetheless shows the "Cancel Booking" button instead of "Record Checkout Video".
Expected Behavior
The button gated on status == ongoing (ButtonRecordVideoCheckout) should render when the underlying Firestore document's status field is genuinely "ongoing", instead of the button gated on status == upcoming.
Steps to Reproduce
What has already been checked and ruled out
Firestore Security Rules — the booking document is fully readable; the status field is visible both in the Firebase console and via the in-app debug text widgets described above. No rule is masking or altering the field.
Query / document caching — retested with a completely fresh Test Mode session (full from-scratch compile: "Configuring build settings…" → "Checking for dependency conflicts…" → "Compiling your project source code…"), not an Instant Reload. The bug reproduces identically on a clean compile, ruling out a stale cached document snapshot.
Stale build / stale session — same as above; reproduced on multiple independent from-scratch Test Mode builds, in new debug sessions each time.
Recomputation of the condition using a different widget-tree construct ("Row recomputation") — the original if (...) Expanded(child: ...) pattern inside the Row's children list was replaced with two separate, explicit ConditionalBuilder widgets (IF <condition> THEN <widget> ELSE <widget>), a structurally different FlutterFlow code-generation path. Both ConditionalBuilders were individually re-opened and verified in the builder UI to have exactly the intended condition and argument binding:
ConditionalBuilder Pages can be renamed to invalid names #1: IF getBookingStatusName(a) == 'upcoming' THEN Button ELSE Container, argument bookingRef → bookingRefDoc
ConditionalBuilder Radio button initial value is blank #2: IF getBookingStatusName(a) == 'ongoing' THEN ButtonRecordVideoCheckout ELSE Container, argument bookingRef → bookingRefDoc
The bug reproduced identically with this alternate implementation: the "ongoing" card still showed the Cancel button and an empty Container in place of the video button.
Precomputing the condition into a separate variable instead of calling the custom function inline inside each condition — no change in behavior.
Flutter Key uniqueness — each list item has a unique key: Key('Key431_${listViewBookingRecord.reference.id}'), ruling out ListView element-recycling/key-collision as the cause.
The custom function itself — getBookingStatusName is pure, single-line, and deterministic, with no caching:
Other overrides — a project-wide search for getBookingStatusName shows only 3 usages: the Cancel-button condition, the Record-Video-button condition, and one debug Text widget. No hidden per-instance property override exists elsewhere.
4. Exact source locations (generated code)
File: booking_place_item_widget.dart (component BookingPlaceItem)
Lines ~220–222 — "Cancel Booking" button condition:
if (functions.getBookingStatusName(widget!.bookingRefDoc) ==Booking.upcoming.name)
Expanded(
child:FFButtonWidget(...CancelBookingWidget...),
),
if (functions.getBookingStatusName(widget!.bookingRefDoc) ==Booking.ongoing.name)
Expanded(
child:FFButtonWidget(...selectMedia(isVideo:true)...),
),
Lines ~415–421 — a third, unrelated conditional in the same widget (Cancelled → "Re-Book" button, resets status to upcoming), included for completeness since it lives in the same file/widget tree.
(Line numbers are as shown in FlutterFlow's Developer Menu → View Code panel at the time of inspection; they may shift slightly if the component is edited further.)
Widget instantiation (from the parent my_booking_widget.dart, for reference — confirms unique keying per list item):
Impact
Users with an "ongoing" booking cannot see or tap the "Record Checkout Video" button, which is required to complete their checkout video recording, and are instead shown an irrelevant "Cancel Booking" action for a booking that is already in progress. This blocks the app's core checkout flow for any booking currently marked "ongoing".
Request
Given that both the underlying data and both possible widget-tree implementations of the conditional rendering have been verified correct through multiple independent checks, this appears to be a FlutterFlow platform/code-generation issue affecting conditional widget visibility within a Row, rather than a project-configuration mistake. We would appreciate the FlutterFlow team's help reproducing and investigating this, and can provide project access / a shareable Test Mode link on request.
Reproducible from Blank
The steps to reproduce above start from a blank project.
- FlutterFlow version: FlutterFlow v7.0.81
- Platform: Web
- Browser name and version: Chrome (last version)
- Operating system and version affected: Windows
Can we access your project?
Current Behavior
FlutterFlow Bug Report — Conditional widgets in a Row render the wrong branch
Project: ZhenilKey (formerly "EasyKey"), project ID
easy-key-ehowpzComponent:
BookingPlaceItem(custom component, used as a list item inside a ListView on the "My Bookings" page)Generated file:
booking_place_item_widget.dart(as shown in FlutterFlow's Developer Menu → View Code)Builder mode: Widget Tree / Test Mode (legacy Test Mode, fresh from-scratch compiles — not Instant Reload)
Inside
BookingPlaceItem, a singleRowcontains two buttons that are each meant to appear only for one specific booking status:Button ("Cancel Booking") — should render only when
status == upcomingButtonRecordVideoCheckout ("Record Checkout Video") — should render only when
status == ongoingFor a real Firestore booking document whose
statusfield is"ongoing", the wrong button renders (the "Cancel Booking" button, which is gated onupcoming), and the correct button (ButtonRecordVideoCheckout, gated onongoing) does not render — an empty gap appears in its place instead.This happens even though:
The document's
statusfield is genuinely"ongoing"(confirmed multiple ways, see §2).The visibility conditions on both buttons, read directly from the widget tree / generated code, are correct and mutually exclusive (see §4).
The bug reproduces identically after replacing the conditional-rendering implementation with a structurally different FlutterFlow construct (see §3, item 4).
Three temporary debug
Textwidgets were added inside the exact sameRow/card as the two buttons, bound directly to the same component parameter (bookingRefDoc) that the button conditions use:bookingRefDoc.status.name→ prints "ongoing"bookingRefDoc.status == Booking.ongoing(boolean) → prints "true"A custom debug function
getBookingIsOngoingDebug→ prints "ongoing"All three debug texts render inside the same bordered card as the misbehaving buttons (confirmed via a tight, zoomed screenshot of the single card), so there is no ambiguity about which list item/card is being inspected. The real, live status is unambiguously
"ongoing"for the card that nonetheless shows the "Cancel Booking" button instead of "Record Checkout Video".Expected Behavior
The button gated on status == ongoing (ButtonRecordVideoCheckout) should render when the underlying Firestore document's status field is genuinely "ongoing", instead of the button gated on status == upcoming.
Steps to Reproduce
Firestore Security Rules — the booking document is fully readable; the
statusfield is visible both in the Firebase console and via the in-app debug text widgets described above. No rule is masking or altering the field.Query / document caching — retested with a completely fresh Test Mode session (full from-scratch compile: "Configuring build settings…" → "Checking for dependency conflicts…" → "Compiling your project source code…"), not an Instant Reload. The bug reproduces identically on a clean compile, ruling out a stale cached document snapshot.
Stale build / stale session — same as above; reproduced on multiple independent from-scratch Test Mode builds, in new debug sessions each time.
Recomputation of the condition using a different widget-tree construct ("Row recomputation") — the original
if (...) Expanded(child: ...)pattern inside theRow's children list was replaced with two separate, explicitConditionalBuilderwidgets (IF <condition> THEN <widget> ELSE <widget>), a structurally different FlutterFlow code-generation path. BothConditionalBuilders were individually re-opened and verified in the builder UI to have exactly the intended condition and argument binding:ConditionalBuilder Pages can be renamed to invalid names #1:
IF getBookingStatusName(a) == 'upcoming' THEN Button ELSE Container, argumentbookingRef→bookingRefDocConditionalBuilder Radio button initial value is blank #2:
IF getBookingStatusName(a) == 'ongoing' THEN ButtonRecordVideoCheckout ELSE Container, argumentbookingRef→bookingRefDocThe bug reproduced identically with this alternate implementation: the "ongoing" card still showed the Cancel button and an empty
Containerin place of the video button.Precomputing the condition into a separate variable instead of calling the custom function inline inside each condition — no change in behavior.
Flutter
Keyuniqueness — each list item has a unique key:Key('Key431_${listViewBookingRecord.reference.id}'), ruling out ListView element-recycling/key-collision as the cause.The custom function itself —
getBookingStatusNameis pure, single-line, and deterministic, with no caching:Other overrides — a project-wide search for
getBookingStatusNameshows only 3 usages: the Cancel-button condition, the Record-Video-button condition, and one debug Text widget. No hidden per-instance property override exists elsewhere.4. Exact source locations (generated code)
File:
booking_place_item_widget.dart(componentBookingPlaceItem)Lines ~220–222 — "Cancel Booking" button condition:
Lines ~272–274 — "Record Checkout Video" button condition:
Lines ~415–421 — a third, unrelated conditional in the same widget (Cancelled → "Re-Book" button, resets status to
upcoming), included for completeness since it lives in the same file/widget tree.(Line numbers are as shown in FlutterFlow's Developer Menu → View Code panel at the time of inspection; they may shift slightly if the component is edited further.)
Widget instantiation (from the parent
my_booking_widget.dart, for reference — confirms unique keying per list item):Users with an "ongoing" booking cannot see or tap the "Record Checkout Video" button, which is required to complete their checkout video recording, and are instead shown an irrelevant "Cancel Booking" action for a booking that is already in progress. This blocks the app's core checkout flow for any booking currently marked "ongoing".
Given that both the underlying data and both possible widget-tree implementations of the conditional rendering have been verified correct through multiple independent checks, this appears to be a FlutterFlow platform/code-generation issue affecting conditional widget visibility within a
Row, rather than a project-configuration mistake. We would appreciate the FlutterFlow team's help reproducing and investigating this, and can provide project access / a shareable Test Mode link on request.Reproducible from Blank
Bug Report Code (Required)
ITFfk/Lqx8pgoflc0a6JdcJF9WMWOWUcTeU30+thcw4bI+PxOoY2OffRQEptWOqHY1ZmI2GgpE4Cw636iIbPKMArPQSrfqJzyahTUxDjcGK6VpvTPJbtY0d6TMBVJ2qM0abQuglvIulvLVI92DmmItiub3qCf9qOYwx5e6fDbOY=
Visual documentation
Environment
Additional Information
No response