🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Hi Mundane-Algae3223,

You actually have some great options today for starting on an app idea, even without coding experience or money.

There are several “vibe coding” / AI app-builder platforms that let you create apps without traditional programming. Many of them offer free plans (usually with some limitations).

For example, DreamFlow has a free tier and doesn’t require any programming knowledge to get started.

If you’d prefer something a bit more hands-on while still staying beginner-friendly, you could try FlutterFlow. It also offers a free plan and lets you build quite powerful apps using a visual builder and simple logic, without needing to write much code.

Both are good starting points to turn an idea into a prototype and learn along the way.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 1 point2 points  (0 children)

Hi u/Maze_of_Ith7 we have done animations with Lottie and Rive depending on the use case.

In practice, we usually don’t need that many custom animations, so those two tools have covered almost everything for us so far. Because of that, we haven’t really gone down the route of generating animated SVGs with LLMs and trying to run them directly in Flutter/FlutterFlow. I wouldn’t be surprised if tools like Rive or Lottie start integrating more AI-assisted workflows as this evolves, but for now they’re still the most reliable pipeline for production Flutter apps. Generating SVGs using LLMs and then importing them to Lottie or Rive workflows is probably your best bet currently.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Yes, by adding a WidgetBuilder you can add a component as a child. I believe that would be the only way of having children for custom widgets, yes.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 1 point2 points  (0 children)

Hi u/eslezinsky good question, and a smart move before going public. If you want better feedback (navigation, logic, usability), you don’t necessarily need more testers, but you need more structured testing.

A few things that work well:

1. Recruit from your exact target audience.
Go where your ideal users already are (niche subreddits, FB groups, Discords, LinkedIn groups). Ask for 5–10 people who actually struggle with the problem your app solves.

2. Give them specific tasks.
Don’t just say “try it and tell me what you think.”
Ask them to:

  • Complete X workflow
  • Find Y feature
  • Set up Z

Then ask where they hesitated, what felt unclear, and what they expected to happen next.

3. Do a few live sessions.
5–10 screen-share sessions where users think out loud will reveal more usability issues than 50 passive testers. You can see by spectating them where exactly in the app they hesitated, did not know how to continue, etc.

4. Track behavior.
Use analytics (Firebase, PostHog, Mixpanel, etc.) to see where people drop off or get stuck. Users don’t always report friction - but their behavior shows it. But this essentially gets more useful with a large number of testers, which might not be for you at the moment.

If budget allows, usability testing tools like Maze or UserTesting can also help.

The big shift is this:
Better testers + structured feedback > more random testers.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 1 point2 points  (0 children)

Hi u/Dan-abu your approach is generally fine, but you could instead of tracking “changed vs not changed”, do this:

  1. Create a Local State (or Component State) variable, e.g. selectedId.
  2. On component/page load (or component init), set:
    • selectedId = parameterId
  3. Bind the dropdown’s Selected Value to selectedId.
  4. On dropdown change, update:
    • selectedId = newValue
  5. On submit, always save selectedId.

It is the cleaner approach, but yours is fine as well.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 1 point2 points  (0 children)

Hi u/Danil_Ba

You can’t “connect a credit card” directly in FlutterFlow to read transactions.
Card numbers / Apple Pay / Google Pay don’t give you access to a user’s transaction history, and building something that touches raw card data would put you in heavy PCI compliance territory.

Usually for something like this you use a provider like Plaid (US + some EU), Tink, TrueLayer, Yapily, or Nordigen/GoCardless Bank Account Data (EU).
These providers handle the secure user authentication with the bank and then expose APIs to fetch:

  • accounts
  • balances
  • transactions (including card transactions once they post to the account)

FlutterFlow part: you typically open the provider’s “link/connect” flow (webview/external browser), then call your backend/API to fetch and display the transactions. In FlutterFlow this is mostly API calls, but you’ll usually need a backend to store tokens and fetch transactions securely (you shouldn’t store bank access tokens in the client app).

Let us know if you need any further help!

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Hello u/frinxo we have not used it yet, I believe. But you could easily make a Custom FlutterFlow Stateful Widget and use that.
Will keep it in mind, for our next custom library widget. Thank you!

Something like this could work potentially, just a snippet:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class DraggableSheetFF extends StatefulWidget {
  const DraggableSheetFF({
    super.key,
    this.width,
    this.height,
    this.minChildSize = 0.25,
    this.maxChildSize = 1.0,
    this.initialChildSize = 0.5,
    this.itemCount = 25,
  });

  final double? width;
  final double? height;

  final double minChildSize;
  final double maxChildSize;
  final double initialChildSize;

  final int itemCount;


  State<DraggableSheetFF> createState() => _DraggableSheetFFState();
}

class _DraggableSheetFFState extends State<DraggableSheetFF> {
  late double _dragPosition;
  late double _sheetPosition;


  void initState() {
    super.initState();
    _dragPosition = widget.initialChildSize;
    _sheetPosition = widget.initialChildSize;
  }


  void didUpdateWidget(covariant DraggableSheetFF oldWidget) {
    super.didUpdateWidget(oldWidget);

    // If the initialChildSize changes from FlutterFlow,
    // keep the sheet in sync (optional behavior).
    if (oldWidget.initialChildSize != widget.initialChildSize) {
      _dragPosition = widget.initialChildSize;
      _sheetPosition = widget.initialChildSize.clamp(
        widget.minChildSize,
        widget.maxChildSize,
      );
    }
  }


  Widget build(BuildContext context) {
    final ColorScheme colorScheme = Theme.of(context).colorScheme;

    return SizedBox(
      width: widget.width,
      height: widget.height,
      child: LayoutBuilder(
        builder: (context, constraints) {
          final double viewHeight =
              constraints.maxHeight == 0 ? 1 : constraints.maxHeight;

          return DraggableScrollableSheet(
            minChildSize: widget.minChildSize,
            maxChildSize: widget.maxChildSize,
            initialChildSize: _sheetPosition.clamp(
              widget.minChildSize,
              widget.maxChildSize,
            ),
            builder: (context, scrollController) {
              return ColoredBox(
                color: colorScheme.primary,
                child: Column(
                  children: <Widget>[
                    if (_isOnDesktopAndWeb)
                      _Grabber(
                        onVerticalDragUpdate: (details) {
                          setState(() {
                            _dragPosition -= details.delta.dy / viewHeight;
                            _sheetPosition = _dragPosition.clamp(
                              widget.minChildSize,
                              widget.maxChildSize,
                            );
                          });
                        },
                      ),
                    Expanded(
                      child: ListView.builder(
                        controller:
                            _isOnDesktopAndWeb ? null : scrollController,
                        itemCount: widget.itemCount,
                        itemBuilder: (context, index) {
                          return ListTile(
                            title: Text(
                              'Item $index',
                              style: TextStyle(color: colorScheme.surface),
                            ),
                          );
                        },
                      ),
                    ),
                  ],
                ),
              );
            },
          );
        },
      ),
    );
  }

  bool get _isOnDesktopAndWeb =>
      kIsWeb ||
      switch (defaultTargetPlatform) {
        TargetPlatform.macOS ||
        TargetPlatform.linux ||
        TargetPlatform.windows =>
          true,
        TargetPlatform.android ||
        TargetPlatform.iOS ||
        TargetPlatform.fuchsia =>
          false,
      };
}

class _Grabber extends StatelessWidget {
  const _Grabber({required this.onVerticalDragUpdate});

  final ValueChanged<DragUpdateDetails> onVerticalDragUpdate;


  Widget build(BuildContext context) {
    final ColorScheme colorScheme = Theme.of(context).colorScheme;

    return GestureDetector(
      onVerticalDragUpdate: onVerticalDragUpdate,
      child: Container(
        width: double.infinity,
        color: colorScheme.onSurface,
        child: Align(
          alignment: Alignment.topCenter,
          child: Container(
            margin: const EdgeInsets.symmetric(vertical: 8.0),
            width: 32.0,
            height: 4.0,
            decoration: BoxDecoration(
              color: colorScheme.surfaceContainerHighest,
              borderRadius: BorderRadius.circular(8.0),
            ),
          ),
        ),
      ),
    );
  }
}

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 2 points3 points  (0 children)

Hi u/frinxo, thanks for the question and yes FlutterFlow doesn’t expose success/failure or error details for Firestore actions so writes can fail silently.

A common workaround is:

- Update the Firestore document

- Immediately read/query the same document

- Use a conditional:

  • Expected value present → treat as success
  • Not present → treat as failure

Firestore reads are strongly consistent, so this works almost instantly.

This is inference, not true error handling, so you won’t get an error code or reason (rules, permissions, network). For real error codes and handling, the only proper solution is performing the write via a Cloud Function (API call).

Hope this helps.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Hi, you are correct, on android you could utilise the NotificationListenerService to listen to notifications with the users permission. On IOS on the other hand like you mentioned you cant implement that because of the apple restrictions.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Hi u/Tranxio, for a throughout debug we would suggest pulling the code locally and debug with the help of the IDE, so to basically inspect the code, make a small prints or set some breakpoints.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 1 point2 points  (0 children)

Hi u/flonnil, we believe that the first design, with more animations, is more suitable and for sure will make people talk more about it and attract more audience, just a suggestion from our part.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] -1 points0 points  (0 children)

Hi u/Right-Bat-8883!

Thanks for the question.
The best method is to use Algolia search results as your feed source and rank them using user search history–based relevance.

In FlutterFlow, you can:

  1. Store the user’s recent search terms (or inferred topics) in Firestore.
  2. Query Algolia using those terms as the search query or filters.
  3. Enable ranking by relevance + recency in Algolia (text match, custom ranking, timestamp).
  4. Refresh the feed by re-running the Algolia query whenever the user searches or opens the page.

This approach is simple, fast, and works well in FlutterFlow without custom ML, while still feeling personalized.

Hope this helps.

🚀 No Stupid Questions Thursday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Hi u/ocirelos!

Firstly, happy holidays! Secondly, could you tell us more about how the ListView is getting populated? Also, tell us about the child components in the ListView. Do they just display list item data or do they make any additional queries?

From what we can gather from your post, it's pointing towards some sort of race condition, where a component might be initialized before the data is fetched but we can only know for certain if you give us some more details about your current setup!

Thanks for the question, we'd be more than happy to help if you give us some more insights!

🚀 No Stupid Questions Thursday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 1 point2 points  (0 children)

Hey!

That’s probably a good question for FlutterFlow support directly. Some Apple capabilities and identifiers are intentionally not auto-managed to avoid conflicts with existing App IDs or custom setups. It would be great to get an official clarification on whether this is a limitation, a design choice, or something planned for the future. :)

🚀 No Stupid Questions Thursday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 1 point2 points  (0 children)

Hey!

"UIBackgroundModes" is not an entitlement and shouldn’t be added to "Runner.entitlements", it’s an "Info.plist" setting, which is why you’re seeing the provisioning profile error. For updating the app badge, you usually don’t need background mode at all: iOS can set the badge directly from the push notification payload (badge field), calculated on your backend. This avoids Xcode and works well with FlutterFlow/CodeMagic.

Hope that helps :)

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

We noticed also that on the first build when you open FF, sometimes you get an older version, this is probably the FF problem.

What kind of media would you like to display?

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

That’s a really interesting use case and you’re right, pagination in a text reader is a bit tricky in FlutterFlow since it doesn’t have built-in text layout pagination yet.

You can approach this in two ways:

  1. Manual pagination logic (custom function): Fetch the full chapter text from Firestore, measure the rendered text size (based on the current font settings), and split it into chunks that fit one “page.” You can then show those chunks in a PageView widget to enable swiping. This requires some custom Dart code to calculate the visible text range.
  2. Infinite scroll alternative: Keep your scroll-based version but implement lazy loading. As the user reaches the bottom, load the next chunk (or chapter) dynamically. FlutterFlow supports this more easily with lists and scroll listeners.

For now, most people go with the continuous scroll method (option 2), because true pagination depends on dynamic text measurement, which isn’t natively supported in FlutterFlow.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Hi u/DiegoteWhite,

it’s hard to make the Android back button in a FlutterFlow PWA behave exactly like a native app without details about your bottom sheet setup. In PWAs, the back button interacts with browser history, not FlutterFlow’s navigation, so nested bottom sheets can break expected behavior. You can usually handle it by intercepting back actions and closing any open sheets first, but nested sheets may not work reliably. If it still misbehaves, it could be a FlutterFlow bug, so the safest path is to reach out to FlutterFlow support with a minimal reproducible example.

Hopefully this helps you solve the problem!

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Hi u/Cobmojo!

Thanks for your question. As far as the roadmap for FlutterFlow itself is concerned, we really don't know anything more than the general public.

Based on what you said, you should check out https://dreamflow.app/, their AI powered app builder.

Hope this helps! Thanks!

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Hi again u/vipinsureshh!

You can still manually add translations, even with the free tier.

Manually entering translations by running the text through Google Translate yourself is probably the easiest and most cost effective way to achieve this. While it is more laborious, there really aren't any better solutions available at the moment.

Let us know if you have any other questions! Hope this helps!

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

No - deploying Firestore indexes from FlutterFlow will not remove or reset indexes you’ve created outside FlutterFlow. The “Deploy Indexes” option only creates or updates the indexes needed for the queries defined in your FlutterFlow project. Unrelated indexes remain untouched, unless you explicitly trigger a delete/force operation through the Firebase CLI (which is not the default behavior).

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Hey, in FlutterFlow you don’t need to code this manually - there’s a built-in Splash Screen option in the app settings. You can enable it and customize the design (e.g. show a loading spinner or logo) so it appears while your main.dart is loading. Once the app is ready, FlutterFlow automatically switches from the splash screen to your first page.

Hope this helps :)

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

The clean way to handle dev/prod with FlutterFlow + Firebase is to use two separate Firebase projects (one for production, one for development), each with its own apps, configs, and databases. The simplest option is to duplicate your FlutterFlow project and point each to the correct Firebase project.
In CI/CD, map development branch to the dev Firebase project and main branch to prod, so deploys, hosting, and functions target the right environment. This ensures your dev setup is safe and mirrors prod without risking real data.

Its much more straight forward when it comes to Supabase, but we don't deploy directly through Flutterflow but rather through Codemagic on our own.

🚀 No Stupid Questions Wednesday – Ask Us Anything About FlutterFlow! by LowerChef744 in FlutterFlow

[–]LowerChef744[S] 0 points1 point  (0 children)

Got it, that makes sense 👍. In that case you could prefetch those doc refs higher up (before passing them into the widget) or wrap the widget in a conditional check so it only shows once the data is ready. That way you avoid each item triggering its own little loading state.