diff --git a/docs/ff-concepts/advanced/custom-login-routing.md b/docs/ff-concepts/advanced/custom-login-routing.md new file mode 100644 index 00000000..4443871b --- /dev/null +++ b/docs/ff-concepts/advanced/custom-login-routing.md @@ -0,0 +1,123 @@ +--- +keywords: ['firebase', 'custom', 'routing'] +slug: /custom-login-routing +title: Custom Login Routing +--- + +# Custom Login Routing + +This article explains how to configure custom routing logic for users after they log in, using a mission control (checkup) page. You can route users differently based on their admin status or whether they’ve completed onboarding. + +:::info[Prerequisites] +- A FlutterFlow project with **Firebase** set up. +- Authentication configured in the project. +- The following app pages created: + - `LoginPage` + - `OnboardingPage` + - `AdminHomePage` + - `UserHomePage` + - `CheckupPage` (Mission Control Page) +::: + +**Create a Local State Variable** + + Create a local state variable to track whether the user is logging in for the first time. + + 1. Go to **Local State** > **+ Add State Variable**. + 2. Name the variable `firstTime`. + 3. Set the type to `Boolean` and enable **Persist**. + + :::tip + The **Persist** setting retains the value locally on the device until the app is uninstalled. It will reset on every refresh when testing in a web browser. + ::: + + ![](imgs/20250430121414406250.png) + + ![](imgs/20250430121414639307.png) + +**Add a User Field for Admin Check** + + 1. Open **Firebase** > **User Collection** > **+ Add Field**. + 2. Create a field called `isAdmin` and set the type to `Boolean`. + + This allows conditional routing based on the admin role. + + ![](imgs/20250430121414890408.png) + + ![](imgs/20250430121415192057.png) + +**Configure Initial Pages** + + 1. Go to **Settings & Integrations** > **App Details** > **Initial Page**. + 2. Set: + - **Entry Page** to `LoginPage` + - **Logged In Page** to `CheckupPage` + + :::tip + **Entry Page** appears when no user is logged in. + **Logged In Page** is used when a user is already authenticated. + ::: + + ![](imgs/20250430121415472919.png) + +**Define Actions on the Checkup Page** + +1. **Check If User Is Logged In** + + 1. Open the **CheckupPage** in the **Action Flow Editor**. + 2. Under **On Page Load**, add a **Conditional Action**. + 3. Set source to `Global Properties` > `Is User Logged In`. + + - If `FALSE`: + - Add action: **Navigate To** `LoginPage`, disable **Back Navigation**, then **Add Terminate**. + + ![](imgs/20250430121434550471.png) + + ![](imgs/20250430121434823464.png) + + ![](imgs/20250430121435145067.png) + +2. **Check If User Is New (First Time Login)** + + 1. Under the `TRUE` branch of "Is User Logged In", add another **Conditional Action**. + 2. Set condition: `Local State` > `firstTime`. + + - If `TRUE`: + - Add action: **Navigate To** `OnboardingPage`, disable **Back Navigation**, then **Add Terminate**. + + ![](imgs/20250430121435792377.png) + +3. **Check If User Is an Admin** + + 1. Under the `FALSE` branch of `firstTime`, add a **Conditional Action**. + 2. Set condition: `Authenticated User` > `isAdmin`. + + - If `TRUE`: + - Navigate to `AdminHomePage`, disable back navigation, then **Terminate**. + + - If `FALSE`: + - Navigate to `UserHomePage`, disable back navigation, then **Terminate**. + + ![](imgs/20250430121436144376.png) + +**Update `firstTime` After Onboarding** + + To avoid showing the onboarding page again, update the `firstTime` variable after onboarding: + + 1. On the `OnboardingPage`, select the **Start** button. + 2. Open the **Action Flow Editor**. + 3. Add action: **Update Local State** > `firstTime` → set value → `False`. + 4. Add navigation: **Navigate To** `CheckupPage`, disable back navigation. + + ![](imgs/20250430121436460665.png) + + ![](imgs/20250430121436751661.png) + +:::tip +You can reuse the `CheckupPage` to add more advanced routing conditions, such as checking if the user has completed their profile or enabled certain settings. +::: + +To skip onboarding for admins as well, extend your logic by nesting onboarding logic inside the admin check condition. + +![](imgs/20250430121437067417.png) + diff --git a/docs/ff-concepts/advanced/imgs/20250430121414406250.png b/docs/ff-concepts/advanced/imgs/20250430121414406250.png new file mode 100644 index 00000000..b7261017 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121414406250.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121414639307.png b/docs/ff-concepts/advanced/imgs/20250430121414639307.png new file mode 100644 index 00000000..d7bc5051 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121414639307.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121414890408.png b/docs/ff-concepts/advanced/imgs/20250430121414890408.png new file mode 100644 index 00000000..90d6f2ca Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121414890408.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121415192057.png b/docs/ff-concepts/advanced/imgs/20250430121415192057.png new file mode 100644 index 00000000..aa2fa203 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121415192057.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121415472919.png b/docs/ff-concepts/advanced/imgs/20250430121415472919.png new file mode 100644 index 00000000..c66cb04e Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121415472919.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121434550471.png b/docs/ff-concepts/advanced/imgs/20250430121434550471.png new file mode 100644 index 00000000..fab7f446 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121434550471.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121434823464.png b/docs/ff-concepts/advanced/imgs/20250430121434823464.png new file mode 100644 index 00000000..ab106c06 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121434823464.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121435145067.png b/docs/ff-concepts/advanced/imgs/20250430121435145067.png new file mode 100644 index 00000000..204338e5 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121435145067.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121435792377.png b/docs/ff-concepts/advanced/imgs/20250430121435792377.png new file mode 100644 index 00000000..f0f114bf Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121435792377.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121436144376.png b/docs/ff-concepts/advanced/imgs/20250430121436144376.png new file mode 100644 index 00000000..b0a60402 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121436144376.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121436460665.png b/docs/ff-concepts/advanced/imgs/20250430121436460665.png new file mode 100644 index 00000000..ba5a4841 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121436460665.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121436751661.png b/docs/ff-concepts/advanced/imgs/20250430121436751661.png new file mode 100644 index 00000000..11db2df5 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121436751661.png differ diff --git a/docs/ff-concepts/advanced/imgs/20250430121437067417.png b/docs/ff-concepts/advanced/imgs/20250430121437067417.png new file mode 100644 index 00000000..7aad0936 Binary files /dev/null and b/docs/ff-concepts/advanced/imgs/20250430121437067417.png differ diff --git a/docs/ff-concepts/animations/animation_gifs/20250430121406506215.gif b/docs/ff-concepts/animations/animation_gifs/20250430121406506215.gif new file mode 100644 index 00000000..40216b21 Binary files /dev/null and b/docs/ff-concepts/animations/animation_gifs/20250430121406506215.gif differ diff --git a/docs/ff-concepts/animations/animation_gifs/20250430121406885071.png b/docs/ff-concepts/animations/animation_gifs/20250430121406885071.png new file mode 100644 index 00000000..8c0556aa Binary files /dev/null and b/docs/ff-concepts/animations/animation_gifs/20250430121406885071.png differ diff --git a/docs/ff-concepts/animations/animation_gifs/20250430121407233519.png b/docs/ff-concepts/animations/animation_gifs/20250430121407233519.png new file mode 100644 index 00000000..3d9c7986 Binary files /dev/null and b/docs/ff-concepts/animations/animation_gifs/20250430121407233519.png differ diff --git a/docs/ff-concepts/animations/animation_gifs/20250430121407654843.png b/docs/ff-concepts/animations/animation_gifs/20250430121407654843.png new file mode 100644 index 00000000..2fc2846b Binary files /dev/null and b/docs/ff-concepts/animations/animation_gifs/20250430121407654843.png differ diff --git a/docs/ff-concepts/animations/animation_gifs/20250430121407938780.png b/docs/ff-concepts/animations/animation_gifs/20250430121407938780.png new file mode 100644 index 00000000..81c77469 Binary files /dev/null and b/docs/ff-concepts/animations/animation_gifs/20250430121407938780.png differ diff --git a/docs/ff-concepts/animations/animation_gifs/20250430121408203472.gif b/docs/ff-concepts/animations/animation_gifs/20250430121408203472.gif new file mode 100644 index 00000000..7161c217 Binary files /dev/null and b/docs/ff-concepts/animations/animation_gifs/20250430121408203472.gif differ diff --git a/docs/ff-concepts/animations/custom-loading-bottom-sheet.md b/docs/ff-concepts/animations/custom-loading-bottom-sheet.md new file mode 100644 index 00000000..d8308936 --- /dev/null +++ b/docs/ff-concepts/animations/custom-loading-bottom-sheet.md @@ -0,0 +1,72 @@ +--- +keywords: ['make', 'custom', 'indicator', 'bottom sheet', 'loading'] +slug: /custom-loading-bottom-sheet +title: Create a Custom Loading Animation Using a Bottom Sheet +--- + +# Create a Custom Loading Animation Using a Bottom Sheet + +Use a custom `Bottom Sheet` to display a loading animation while performing long-running actions such as API calls, database writes, or chained workflows. This guide walks through how to build a non-blocking custom loading indicator. + +![](animation_gifs/20250430121406506215.gif) + +:::info[Prerequisites] +- A `Bottom Sheet` component with a loading animation (e.g., Lottie, GIF, or static image) +- A page where you want to trigger the loading sequence +::: + +1. **Create a Bottom Sheet Component** + + 1. Go to the **UI Builder** and create a new `Component`. + 2. Select the **Bottom Sheet** layout. + 3. Add a loading animation: + - Use a **Lottie** animation, **GIF**, or any custom UI for the loading indicator. + - You can also include a `Text` widget to display a status message. + + ![](animation_gifs/20250430121406885071.png) + + This component will serve as the visual loading indicator during your action chain. + +2. **Set Up the Action Workflow** + + On the page where you want to trigger the loading sequence: + + 1. **Trigger the workflow** (e.g., on button press). + 2. Add a `Delay` action to simulate a task (optional). + 3. Add the `Open Bottom Sheet` action and configure it to be **non-blocking**. + + ![](animation_gifs/20250430121407233519.png) + + ![](animation_gifs/20250430121407654843.png) + + :::warning + Enable the **Non Blocking** option in the `Open Bottom Sheet` action. This allows the workflow to continue running while the bottom sheet is visible. + ::: + +3. **Add the Main Actions** + + 1. Add the primary actions you want to perform while the loading indicator is active. + - These could include `API Calls`, `Create Document`, `Update Document`, or chained actions. + 2. For demonstration, a `Delay` of 5 seconds is used to simulate long-running tasks. + +4. **Dismiss the Bottom Sheet** + + Once all actions are complete: + + 1. Add a `Close Bottom Sheet` action to remove the loading indicator. + + ![](animation_gifs/20250430121407938780.png) + +5. **Show a Confirmation Message** + + 1. Add a `Show SnackBar` action to display a success message to the user. + + This confirms that the actions are complete and the bottom sheet has been dismissed. + + ![](animation_gifs/20250430121408203472.gif) + +You can test this implementation in the public project: + - Navigate to the **CustomLoading** page + - Tap **Login** on the login screen using the test account + - Select **Custom Loading** from the home page to view it in action + diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/custom-navbar-setup.md b/docs/ff-concepts/navigation-routing/special-page-navigation/custom-navbar-setup.md new file mode 100644 index 00000000..466c5525 --- /dev/null +++ b/docs/ff-concepts/navigation-routing/special-page-navigation/custom-navbar-setup.md @@ -0,0 +1,82 @@ +--- +keywords: ['custom', 'navbar', 'navigation', 'app bar'] +slug: /custom-navbar-setup +title: Custom Navigation Bars +--- + +# Custom Navigation Bars + +Build a custom `Navigation Bar` (NavBar) to support dynamic views, role-based access, or complex widget layouts such as embedded cart counters or animated icons. Unlike the default NavBar widget, this approach gives full control over design and visibility. + +![](imgs/20250430121449657102.png) + +:::info[Prerequisites] +- A component to be used as the custom NavBar. +- Pages with `Stack` layout to allow overlay positioning. +- Local State variable or conditional logic to control visibility. +::: + +Follow the steps below: + +1. **Build the NavBar Component** + + 1. Create a **Component** and design your NavBar layout. + 2. Add widgets as needed: icons, labels, counters, conditional containers, etc. + 3. Ensure the NavBar’s height is consistent across screens (e.g., `100px`). + +2. **Add the NavBar to Your Pages** + + 1. Wrap the page layout in a `Stack`. + 2. Place the NavBar component inside a `Container` widget. + - Set the container’s vertical alignment to `1` (bottom). + - Set its width and height to match screen width and desired NavBar height. + + ```plaintext + Page + └─ Stack + ├─ Main Page Content + └─ Container (height: 100px, align: bottom) + └─ NavBar Component + ``` + +3. **Configure NavBar Behavior** + + 1. Add `Bottom Padding` to your main page content equal to the NavBar’s height. This prevents the NavBar from overlapping other widgets. + + ![](imgs/20250430121450015102.png) + + 2. Use `Local State`, `App State`, or conditional logic from a database (e.g., `is_admin`) to control: + - Which version of the NavBar appears. + - Whether the NavBar is visible at all. + + :::warning + Avoid placing the custom NavBar on subpages. NavBar components should only be used on top-level pages. Adding back navigation (e.g., `Pop` actions) to these pages may result in routing issues. + ::: + +**Example: Conditional NavBar Logic** + + You can conditionally display different layouts depending on the user’s role: + - **Admin** users may see extra items or a different layout. + - **Standard** users may have limited options. + - Use the `is_admin` field from the `Users` collection to control this logic dynamically. + +**Sample Project:** + + A public sample project is available demonstrating: + - A basic custom NavBar + - A conditional NavBar that changes layout based on user role + + **How to Use the Sample:** + + 1. Launch the project. + 2. Tap **Login** using the pre-configured test user. + 3. Navigate to: + - **Custom NavBar/AppBar** to view a static NavBar layout. + - **Conditional NavBar** to explore role-based NavBar behavior. + - Toggle the `is_admin` field to test both states. + + ![](imgs/20250430121450326812.png) + + ![](imgs/20250430121450591399.png) + + ![](imgs/20250430121450801118.png) diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121318472792.gif b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121318472792.gif new file mode 100644 index 00000000..d2020443 Binary files /dev/null and b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121318472792.gif differ diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121449657102.png b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121449657102.png new file mode 100644 index 00000000..c6dd07a9 Binary files /dev/null and b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121449657102.png differ diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450015102.png b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450015102.png new file mode 100644 index 00000000..dc987298 Binary files /dev/null and b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450015102.png differ diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450326812.png b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450326812.png new file mode 100644 index 00000000..25cd5daa Binary files /dev/null and b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450326812.png differ diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450591399.png b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450591399.png new file mode 100644 index 00000000..06efc6f8 Binary files /dev/null and b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450591399.png differ diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450801118.png b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450801118.png new file mode 100644 index 00000000..b45231f2 Binary files /dev/null and b/docs/ff-concepts/navigation-routing/special-page-navigation/imgs/20250430121450801118.png differ diff --git a/docs/ff-concepts/navigation-routing/special-page-navigation/pageview-widget.md b/docs/ff-concepts/navigation-routing/special-page-navigation/pageview-widget.md index 70f20306..debf90c3 100644 --- a/docs/ff-concepts/navigation-routing/special-page-navigation/pageview-widget.md +++ b/docs/ff-concepts/navigation-routing/special-page-navigation/pageview-widget.md @@ -390,4 +390,55 @@ If you prefer watching a video tutorial, here's the one for you: allowFullScreen allow="clipboard-write"> - \ No newline at end of file + + +## Use Case: Image Carousel with Auto-Scroll + +You can build an image carousel using the `PageView` widget combined with the `Control Page View` action. This allows users to scroll through images either manually or automatically. + +**Steps Overview:** + + 1. **Add a PageView Widget** + - From the **Widget Panel**, drag the `PageView` widget onto the canvas. + - Populate it with your image widgets or bind it to a dynamic image list. + + 2. **Set Up Page Load Action** + - Select the `Scaffold` or main container. + - Add a `Page Load` action to trigger carousel behavior. + + 3. **Add `Control Page View` Action** + - Use the `Control Page View` action to control transitions: + - `Next`, `Previous`, `First`, or `Last`. + + 4. **Auto-Scroll Behavior (Optional)** + - Add a sequence of: + - `Control Page View` → `Wait` → `Control Page View` (Next) + - Loop this logic to create a smooth, timed carousel experience. + + ![Carousel Example](imgs/20250430121318472792.gif) + +## Use Case: Image Slider from List of Image URLs + +This example demonstrates how to build a dynamic image slider using a list of image URLs—ideal for product detail screens or galleries. + +Follow the steps below: + +1. **Add a PageView Widget** + - Place a `PageView` on your screen. + +2. **Bind to the Image List** + - Generate dynamic children from your list of image URLs. + +3. **Add a Repeating Child** + - Use a single `Image` widget inside the `PageView`. + - Bind the `Image URL` to the current list item. + + :::tip + You only need one child inside the PageView. When bound to a list, it automatically repeats for each item. + ::: + + :::tip + - Use horizontal scroll for carousels and onboarding pages. + - Combine with indicators or swipe gestures for a richer UX. + - Use `Wait` and `Control Page View` actions to create auto-scroll behavior. + ::: \ No newline at end of file diff --git a/docs/ff-concepts/notifications/push-notifications.md b/docs/ff-concepts/notifications/push-notifications.md index 0fe7c3e5..2922e264 100644 --- a/docs/ff-concepts/notifications/push-notifications.md +++ b/docs/ff-concepts/notifications/push-notifications.md @@ -237,6 +237,31 @@ In this action, you can decide who should receive the push notification by setti ![trigger push notifications](imgs/trigger-pn.avif) +### Send Notifications to Multiple Users (Dynamic) + +To notify a group of users when a document is created (e.g., group chat, announcement, or event), follow this flow: + +1. **Add a Backend Query** + - Add an **Action** → **Backend Query** before sending the notification. + - Set **Query Type** to `Query Collection` and select your users collection (e.g., `users`). + - Set **Return Type** to `List of Documents`. + +2. **Create a Document** + - Add an **Action** → **Create Document** to store the submitted content (e.g., a post or message). + +3. **Trigger Notification** + - Add an **Action** → **Trigger Push Notification**. + - Set the **audience** to **Multiple Recipients**. + - Under **Recipients**: + - Select **Filter List Items** → **Items in List > Document Exists** to apply conditions. + - Then choose **Map List Items** → `Document Properties` → `Reference` to get user document references. + + The notification will be sent to all users matching your filters, using the queried list. + + :::tip + Use this approach for dynamic group-based notifications tied to app activity, like chat, announcements, or tasks. + ::: + ## Testing Push Notifications Cloud Function You can also test the Push Notifications Cloud Function directly from the Google Cloud console, without needing to trigger from FlutterFlow. This is especially useful for debugging purposes. For step-by-step instructions, including an example and how to structure the request, refer to the [Testing Cloud Functions in Google Cloud Console](../../ff-concepts/adding-customization/cloud-functions.md#testing-cloud-functions-in-google-cloud-console) section. diff --git a/docs/ff-integrations/database/supabase/imgs/20250430121159260138.png b/docs/ff-integrations/database/supabase/imgs/20250430121159260138.png new file mode 100644 index 00000000..3dc5b900 Binary files /dev/null and b/docs/ff-integrations/database/supabase/imgs/20250430121159260138.png differ diff --git a/docs/ff-integrations/database/supabase/imgs/20250430121159528641.png b/docs/ff-integrations/database/supabase/imgs/20250430121159528641.png new file mode 100644 index 00000000..558cab1d Binary files /dev/null and b/docs/ff-integrations/database/supabase/imgs/20250430121159528641.png differ diff --git a/docs/ff-integrations/database/supabase/imgs/20250430121159842724.png b/docs/ff-integrations/database/supabase/imgs/20250430121159842724.png new file mode 100644 index 00000000..e7bbdfaa Binary files /dev/null and b/docs/ff-integrations/database/supabase/imgs/20250430121159842724.png differ diff --git a/docs/ff-integrations/database/supabase/imgs/20250430121200086333.png b/docs/ff-integrations/database/supabase/imgs/20250430121200086333.png new file mode 100644 index 00000000..b4492a8d Binary files /dev/null and b/docs/ff-integrations/database/supabase/imgs/20250430121200086333.png differ diff --git a/docs/ff-integrations/database/supabase/imgs/20250430121200394549.png b/docs/ff-integrations/database/supabase/imgs/20250430121200394549.png new file mode 100644 index 00000000..a269e80b Binary files /dev/null and b/docs/ff-integrations/database/supabase/imgs/20250430121200394549.png differ diff --git a/docs/ff-integrations/database/supabase/supabase-search-implementation.md b/docs/ff-integrations/database/supabase/supabase-search-implementation.md new file mode 100644 index 00000000..d9e16ed9 --- /dev/null +++ b/docs/ff-integrations/database/supabase/supabase-search-implementation.md @@ -0,0 +1,53 @@ +--- +keywords: [search, implementation, tutorial] +slug: /supabase-search-implementation +title: Supabase Search Implementation +--- + +# Supabase Search Implementation + +This article outlines a workaround to implement basic search functionality using Supabase in FlutterFlow. While FlutterFlow does not currently support full Supabase search natively, you can use the Realtime feature combined with input filters for a basic search experience. + +:::info[Prerequisites] +- A Supabase project integrated with your FlutterFlow app. +- Realtime enabled in the relevant Supabase table. +::: + +Follow the steps below to implement Supabase Search: + + - **Enable Realtime in Supabase** + + 1. Open your Supabase project and go to **Table Editor**. + 2. Select the relevant table. + 3. Enable **Realtime** updates from the table settings. + + ![](imgs/20250430121159260138.png) + + ![](imgs/20250430121159528641.png) + + - **Filter Query Data Using an Input Field** + + 4. In FlutterFlow, add an **Input Text Field** to your UI. + 5. Configure your **Query Collection** to apply a filter using the input value. + - Set the filter condition to `is equal to`. + + ![](imgs/20250430121159842724.png) + + - **Choose a Trigger Method for Search** + + - Auto-Search on Input Change + + 6. Enable **Update Page on Change**. + 7. Set the update frequency to your desired interval. + + ![](imgs/20250430121200086333.png) + + - **Manual Search on Submit** + + 8. Refresh the query manually when the input text is submitted. + + ![](imgs/20250430121200394549.png) + +:::warning +Using real-time updates for live search may incur higher costs compared to performing a search on submission. +::: diff --git a/docs/resources/control-flow/backend-logic/api/handle-api-call-errors.md b/docs/resources/control-flow/backend-logic/api/handle-api-call-errors.md new file mode 100644 index 00000000..8c55f7cc --- /dev/null +++ b/docs/resources/control-flow/backend-logic/api/handle-api-call-errors.md @@ -0,0 +1,117 @@ +--- +keywords: ['api', 'error', 'call'] +slug: /handle-api-call-errors +title: Handle API Call Errors +--- + +# Handle API Call Errors + +Proper error handling in API calls helps ensure reliable app behavior and a better user experience. This guide walks through how to manage different API response outcomes in FlutterFlow. + +:::info[Prerequisites] +- A configured API call in your project. +- Basic understanding of FlutterFlow actions and variables. +::: + +1. **Add the API Call Action** + + Start by adding the API call action to your desired trigger (e.g., a button press). + + :::note + Ensure that you name the **Action Output Variable** when configuring the API call. This allows referencing the API response throughout the workflow. + ::: + + ![](imgs/20250430121338595755.png) + +2. **Check API Call Success Status** + + Add a **Conditional Action** to determine if the call was successful. + + ![](imgs/20250430121338981199.png) + + Select the output variable of the API call, then use the built-in boolean field `Succeeded`. This value is `true` if the API call succeeded. + + ![](imgs/20250430121339304862.png) + + :::tip + To handle specific failure cases, use the `Status Code` field in the condition. For example, check if the response returns a `400` status to handle a specific error scenario. + ::: + + ![](imgs/20250430121339561161.png) + + ![](imgs/20250430121339880626.png) + +3. **Add Actions for API Failure** + + If the call fails, display a message to the user. You can use a `Show SnackBar` action and include the status code in the message. + + ![](imgs/20250430121340184264.png) + + Customize the fallback behavior as needed. You may choose to: + - Show an alert dialog + - Navigate to a fallback page + - Retry the request + +4. **Check If the Response Is Valid** + + Sometimes an API returns a `200 OK` status but the response body is not usable due to incorrect input (e.g., an invalid API key). + + ![](imgs/20250430121340477997.png) + + ![](imgs/20250430121340819210.png) + + In this example, the call succeeds but returns no useful data. To handle this: + + 1. Add another conditional action after confirming success. + 2. Check whether a key path in the response (e.g., `full_address`) is set. + + ![](imgs/20250430121341094142.png) + + ![](imgs/20250430121341370572.png) + + Use the “Set / Not Set” condition to verify that expected fields contain data. Based on this, take appropriate follow-up actions. + + :::warning + APIs behave differently—some always return a success code even when there's an error. Always validate the content of your response, not just the status. + ::: + +5. **Handle Valid and Invalid Responses** + + If the expected path is set, proceed with displaying or using the data. + + ![](imgs/20250430121341663566.png) + + If it is not set, display the entire response body for debugging purposes. This can help identify root issues such as authentication errors or misconfigured paths. + +**Example Flow** + + Here is an example of a complete action flow for error handling: + + ![](imgs/20250430121341984539.png) + + This flow ensures: + - The call status is checked. + - The response body is validated. + - Appropriate feedback is shown to the user in every scenario. + +**Output Scenarios** + + - **Failed API Call (e.g., 400 Error)** + + ![](imgs/20250430121342448092.png) + + Displays the error code and allows further investigation. + + - **Success Call with Invalid Response** + + ![](imgs/20250430121342680195.png) + + Shows a fallback message or error details if expected data is missing. + + - **Success Call with Valid Data** + + ![](imgs/20250430121342877952.png) + + Data is used with confidence, and the app behaves as expected. + + ![](imgs/20250430121343302322.gif) diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121338595755.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121338595755.png new file mode 100644 index 00000000..37a4472d Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121338595755.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121338981199.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121338981199.png new file mode 100644 index 00000000..3eaf29a0 Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121338981199.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121339304862.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121339304862.png new file mode 100644 index 00000000..2c06dc85 Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121339304862.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121339561161.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121339561161.png new file mode 100644 index 00000000..3dd049c5 Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121339561161.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121339880626.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121339880626.png new file mode 100644 index 00000000..b3ed0607 Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121339880626.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121340184264.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121340184264.png new file mode 100644 index 00000000..36debd2a Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121340184264.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121340477997.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121340477997.png new file mode 100644 index 00000000..6aee42ae Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121340477997.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121340819210.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121340819210.png new file mode 100644 index 00000000..e26d3c3e Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121340819210.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121341094142.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121341094142.png new file mode 100644 index 00000000..44461f41 Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121341094142.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121341370572.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121341370572.png new file mode 100644 index 00000000..d0457be0 Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121341370572.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121341663566.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121341663566.png new file mode 100644 index 00000000..b7878f1a Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121341663566.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121341984539.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121341984539.png new file mode 100644 index 00000000..ae31e113 Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121341984539.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121342448092.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121342448092.png new file mode 100644 index 00000000..cb6302ca Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121342448092.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121342680195.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121342680195.png new file mode 100644 index 00000000..aae9c8d9 Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121342680195.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121342877952.png b/docs/resources/control-flow/backend-logic/api/imgs/20250430121342877952.png new file mode 100644 index 00000000..a07e676f Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121342877952.png differ diff --git a/docs/resources/control-flow/backend-logic/api/imgs/20250430121343302322.gif b/docs/resources/control-flow/backend-logic/api/imgs/20250430121343302322.gif new file mode 100644 index 00000000..e79fa382 Binary files /dev/null and b/docs/resources/control-flow/backend-logic/api/imgs/20250430121343302322.gif differ diff --git a/docs/resources/control-flow/backend-logic/backend-query/query-collection.md b/docs/resources/control-flow/backend-logic/backend-query/query-collection.md index 37db013e..4486f74e 100644 --- a/docs/resources/control-flow/backend-logic/backend-query/query-collection.md +++ b/docs/resources/control-flow/backend-logic/backend-query/query-collection.md @@ -55,31 +55,32 @@ The instructions to query a Supabase table are almost the same, except that for :::
- + -
-

- - -
- -
-

-
+ /> + + + ## FAQs
Why aren't real-time updates working for my table in Supabase project? @@ -176,4 +179,93 @@ Additionally, you can enable real-time updates when creating a new table. ![enable-realtime-updates-sb-table.avif](../imgs/enable-realtime-updates-sb-table-2.avif)

-
\ No newline at end of file + + +## Example: Filter One Dropdown by Another + +You can filter one dropdown based on the selected value of another. This is useful in nested selection scenarios like choosing a vehicle **make** first, then filtering the **model** dropdown accordingly. + +1. **Set Up Firestore Collections** + + - **`make` Collection** + - Field: `name` (String) — the vehicle make (e.g., BMW) + + - **`model` Collection** + - Fields: + - `name` (String) — model name + - `make_name` (String) — should match the `name` from the `make` collection + +2. **Create the Dropdown UI** + + Add two `Dropdown` widgets: + - **First dropdown** → queries `make` + - **Second dropdown** → queries `model`, filtered by the selected `make` + +3. **Query the First Dropdown** + + - Select the **first dropdown** + - Set the data source to a query on `make` + - Bind the `name` field to the dropdown options + +4. **Filter the Second Dropdown** + + - Select the **second dropdown** + - Set its data source to query the `model` collection + - Add a filter: + - **Field**: `make_name` + - **Condition**: `is equal to` + - **Value**: the selected item from the first dropdown (via `Widget State`) + + :::tip + This method can be extended to chains of 3+ dropdowns using additional filters. + ::: + +## Example: Filter Records by Selected Calendar Date + +You can use a `Calendar` widget to dynamically filter query results by date. This is useful when showing time-sensitive records such as appointments or events. + +:::info[Requirements] +- A Firebase collection with a date field (e.g., `eventDate`) +- A `Calendar` widget on the page +- A `ListView` bound to a Firebase query +::: + +1. **Add Date Filters to the Query** + + Apply two filters to your `ListView` query: + + - **Start of the day** – `eventDate` **≥** selected date (start) + - **End of the day** – `eventDate` **≤** selected date (end) + + Steps: + + 1. Select the `ListView` widget. + 2. In the **Backend Query** section, click **+ Filter** twice. + 3. For both filters, use: + - **Field Name**: `eventDate` + - **Relation**: + - First filter: `Greater Than or Equal` + - Second filter: `Less Than or Equal` + - **Value Source**: `From Variable` → `Widget State` → `calendarSelectedDay` + - Set **Range Part**: + - First filter: `Start` + - Second filter: `End` + +2. **Set the Initial Calendar Date** + + To avoid loading issues: + + 1. Select the `Calendar` widget. + 2. Under **Initial Date**, choose: + - **Source**: `Global Properties` + - **Option**: `Current Timestamp` + + :::warning + Not setting an initial date can lead to a blank screen in Run Mode. + ::: + +**Test the Result:** + + - Run the app. + - Select a date on the calendar. + - The `ListView` will update to show only records from that date.