Skip to content

Commit 71b73df

Browse files
authored
Merge branch 'main' into david/notifications
2 parents 41e2319 + 3ddc41f commit 71b73df

File tree

159 files changed

+2831
-298
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+2831
-298
lines changed

docs/accounts-billing/new-pricing-comparison.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ export const PricingToggles = () => {
342342
<td>Automated Testing<br/><span className="feature-description">Run automated tests on your applications</span></td>
343343
<td>❌</td>
344344
<td>❌</td>
345-
<td></td>
345+
<td>1 test per project</td>
346346
<td>Up to 3 tests per project</td>
347347
<td>Unlimited tests</td>
348348
</tr>
@@ -380,7 +380,7 @@ export const PricingToggles = () => {
380380
</tr>
381381
<tr>
382382
<td>Cloud Functions<br/><span className="feature-description">Write and deploy Firebase Cloud Functions directly from FlutterFlow</span></td>
383-
<td></td>
383+
<td></td>
384384
<td>✅</td>
385385
<td>✅</td>
386386
<td>✅</td>

docs/ff-concepts/adding-customization/code-file.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,4 +459,15 @@ You can access the custom enums from **Set from Variable** menu > **Custom Enum*
459459
- Keep your custom class files modular and focused; ideally one class per file for better organization and reusability.
460460
- Avoid advanced Dart features that are not supported by FlutterFlow’s parser, such as generics or function-typed fields.
461461
- Re-parse your code after making changes to ensure FlutterFlow updates the parsed structure correctly.
462-
- Document your code with comments to make your custom classes easier to understand and maintain over time.
462+
- Document your code with comments to make your custom classes easier to understand and maintain over time.
463+
464+
## FAQs
465+
466+
<details>
467+
<summary>
468+
Can I add Custom Classes (Code Files) in a Library Project?
469+
</summary>
470+
<p>
471+
Yes, you can. When a Library Project is imported, any custom code files you’ve defined will be parsed, and the resulting classes will be available for use in the consuming project.
472+
</p>
473+
</details>

docs/ff-concepts/adding-customization/configuration-files.md

Lines changed: 192 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@ In some cases, you’ll need to tweak the configuration files that FlutterFlow g
1616
Here are the key configuration files you can edit:
1717

1818
- [**`AndroidManifest.xml`**](#androidmanifestxml-android) – Configures app permissions, metadata, and intent filters for Android.
19+
- [**`build.gradle`**](#buildgradle-android) – Defines Android specific build configurations such as compile SDK version, dependencies, build types, and signing configurations.
20+
- [**ProGuard files**](#proguard-file-android) – Used for code shrinking and obfuscation in Android builds.
1921
- [**`Info.plist`**](#infoplist-ios)– Manages iOS app settings, including permissions and configurations.
2022
- [**`Entitlements.plist`**](#entitlementsplist-ios) – Defines iOS app privileges such as push notifications and Apple Pay.
23+
- [**`AppDelegate.swift`**](#appdelegateswift-ios) – Manages iOS app launch behavior and runtime configuration. It registers Flutter plugins, initializes services like Firebase, and handles app lifecycle events and deep linking.
2124
- [**`main.dart`**](#maindart-flutter) – The entry point of your Flutter app, where you can modify app-level logic.
22-
- [**ProGuard files**](#proguard-file-android) – Used for code shrinking and obfuscation in Android builds.
25+
2326

2427
:::warning
2528

@@ -29,17 +32,17 @@ In short, edit native code only when necessary, and do so carefully.
2932

3033
:::
3134

32-
## Editing native XML Files (AndroidManifest.xml, Info.plist, Entitlements.plist)
35+
## Editing Files
3336

34-
FlutterFlow provides two main ways to modify native XML files: [**Add Individual Snippets**](#option-1-add-individual-snippets) and [**Manual Edit Mode**](#option-2-manual-edit-mode).
37+
FlutterFlow provides two main ways to modify native files: [**Add Individual Snippets**](#option-1-add-individual-snippets) and [**Manual Edit Mode**](#option-2-manual-edit-mode).
3538

3639
### Option 1: Add Individual Snippets
3740

3841
**Snippets** are small pieces of code that you can inject into the native files at predefined locations. Instead of opening the whole file to edit, you provide just the fragment you want to add, and FlutterFlow merges it into the file in the correct place. This is safer and easier for small additions such as a permission line or a meta-data tag.
3942

4043
#### Snippet Placement for Android
4144

42-
For Android, modifications are typically made in the `AndroidManifest.xml` file, where you can add the following tags:
45+
Let’s see how to add a snippet for the `AndroidManifest.xml` file, where you can add the following tags:
4346

4447
- **Activity Tags:** Inserts XML code inside the `MainActivity` block. This is typically used to add child XML elements within the MainActivity, such as `<intent-filter>` or `<meta-data>` to control aspects such as deep linking, theme application, or launch mode.
4548
- **Application Tags**: Used to inject properties or attributes directly on the `<application>` tag itself. For example, you can use this to set values such as `android:icon`, `android:label`, `android:allowBackup`.
@@ -75,9 +78,9 @@ To add a snippet to your `AndroidManifest.xml`, navigate to **Custom Code** from
7578

7679
#### Snippet Placement for iOS
7780

78-
For iOS, you can modify the `Info.plist` and `Entitlements.plist` files. There’s no nested application/activity structure like on Android. Instead, both files are dictionaries of key-value pairs. When you add a snippet, it’s placed directly under the root `<dict>` element of these plist files.
81+
For iOS, let’s see how to add a snippet for the `Info.plist` and `Entitlements.plist` files. There’s no nested application/activity structure like on Android. Instead, both files are dictionaries of key-value pairs. When you add a snippet, it’s placed directly under the root `<dict>` element of these plist files.
7982

80-
To add a snippet to native iOS files, navigate to **Custom Code** (from the left-side menu) > **Configuration Files**, and select the desired file (`Info.plist` or `Entitlements.plist`). Click the **plus** (+) button, provide a descriptive name (which will appear as a comment in the file), and paste your snippet code.
83+
To add a snippet to native iOS files, navigate to **Custom Code** (from the left-side menu) > **Configuration Files**, and select the desired file. Click the **plus** (+) button, provide a descriptive name (which will appear as a comment in the file), and paste your snippet code.
8184

8285
<div style={{
8386
position: 'relative',
@@ -396,6 +399,161 @@ If your app needs to communicate over HTTP (unencrypted) for testing or legacy r
396399
You can modify the `AndroidManifest.xml` file by either [**adding a snippet**](#snippet-placement-for-android) or [**editing it manually**](#option-2-manual-edit-mode).
397400
:::
398401

402+
### `build.gradle` (Android)
403+
404+
The `build.gradle` file is the main Gradle build script for your Android app module. It resides in the `android/app/` directory and controls how your Android app is compiled, packaged, and built. This file defines critical configuration such as:
405+
406+
- SDK versions (`compileSdkVersion`, `minSdkVersion`, `targetSdkVersion`)
407+
- Dependencies for third-party libraries
408+
- Build types (like debug vs. release)
409+
- Signing configurations for release builds
410+
- Kotlin and Flutter settings
411+
- MultiDex and ProGuard rules
412+
- Android packaging options
413+
414+
In short, the `build.gradle` file acts as the blueprint for how your Android app is built and prepared for distribution.
415+
416+
**Example 1: Changing SDK Versions**
417+
418+
To set which Android SDK your app compiles with, update the following section in `build.gradle`:
419+
420+
```jsx
421+
android {
422+
compileSdkVersion 33
423+
424+
defaultConfig {
425+
applicationId "com.example.myapp"
426+
minSdkVersion 21
427+
targetSdkVersion 33
428+
versionCode 1
429+
versionName "1.0"
430+
}
431+
}
432+
```
433+
434+
Use this when you want to upgrade to a newer Android API level or need compatibility with certain libraries.
435+
436+
437+
**Example 2: Adding Third-Party Libraries**
438+
439+
To use Android-specific libraries (such as Play Services or Jetpack), add them in the `dependencies` section:
440+
441+
```jsx
442+
dependencies {
443+
implementation 'com.google.android.gms:play-services-maps:18.1.0'
444+
implementation 'androidx.work:work-runtime:2.7.1'
445+
}
446+
```
447+
448+
Use this when integrating services like Google Maps, Firebase Messaging, or WorkManager.
449+
450+
451+
**Example 3: Adding ProGuard Rules for Release Build**
452+
453+
If your app uses ProGuard (code shrinking/obfuscation), you can define custom rules or reference a rules file:
454+
455+
```jsx
456+
android {
457+
buildTypes {
458+
release {
459+
minifyEnabled true
460+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
461+
}
462+
}
463+
}
464+
```
465+
466+
Use this to reduce APK size and protect code in production.
467+
468+
**Example 4: Enabling MultiDex for Large Apps**
469+
470+
If your app exceeds the 64K method limit (common when using many dependencies), enable MultiDex support:
471+
472+
```jsx
473+
defaultConfig {
474+
...
475+
multiDexEnabled true
476+
}
477+
```
478+
479+
Use this when your build fails with `Too many methods` errors or when integrating large libraries like Firebase.
480+
481+
:::tip
482+
You can modify the `build.gradle` file by either [**adding a snippet**](#snippet-placement-for-ios) or [**editing it manually**](#option-2-manual-edit-mode).
483+
:::
484+
485+
### ProGuard File (Android)
486+
487+
The **ProGuard file (`proguard-rules.pro`)** is a configuration file used in Android projects to optimize, shrink, and obfuscate the app’s code. It helps reduce APK or AAB size, improves performance, and protects the app’s code from reverse engineering by making it difficult to decompile.
488+
489+
The ProGuard files allow you to specify rules to keep certain classes or methods (prevent them from being removed or renamed), or to tweak the obfuscation behavior. Located in the **`android/app/proguard-rules.pro`** directory of an Android project, the ProGuard rules are applied when code shrinking is enabled in a release build.
490+
491+
Here are some scenarios where you may need to modify the ProGuard file:
492+
493+
**Example 1: Preventing Issues with Third-Party Libraries**
494+
495+
ProGuard can obfuscate critical libraries, breaking their functionality. To prevent this, you need to keep specific classes used by the library.
496+
497+
```jsx
498+
# Firebase
499+
-keep class com.google.firebase.** { *; }
500+
501+
# Gson (JSON Serialization)
502+
-keep class com.google.gson.** { *; }
503+
-keepattributes *Annotation*
504+
```
505+
506+
This ensures that Firebase and Gson classes are not obfuscated, preventing serialization errors.
507+
508+
**Example 2: Debugging ProGuard Issues**
509+
510+
If your app crashes in release mode but works in debug mode, ProGuard might be removing important classes. To troubleshoot, you can add logging and keep rules.
511+
512+
```jsx
513+
-assumenosideeffects class android.util.Log {
514+
public static *** d(...);
515+
public static *** v(...);
516+
public static *** i(...);
517+
}
518+
```
519+
520+
This removes debug logs in release builds but retains them for troubleshooting.
521+
522+
**Example 3: Improving Security by Removing Debug Information**
523+
524+
Attackers can decompile APKs and view sensitive debug logs. To remove these debug logs, add:
525+
526+
```jsx
527+
-dontwarn android.util.Log
528+
```
529+
530+
531+
**Example 4: Keeping Native Libraries (JNI) Safe**
532+
533+
If your app uses native C/C++ libraries (JNI), ProGuard may mistakenly remove required components. To prevent this:
534+
535+
```jsx
536+
-keep class com.example.native.** { *; }
537+
-keepclassmembers class * {
538+
native <methods>;
539+
}
540+
```
541+
542+
This keeps all native methods intact.
543+
544+
**Example 5: Preventing Issues with Reflection-Based Code**
545+
546+
Some libraries rely on reflection to dynamically call methods, which ProGuard may remove.
547+
548+
```jsx
549+
-keep class * implements android.os.Parcelable { *; }
550+
-keepclassmembers class ** {
551+
@android.webkit.JavascriptInterface <methods>;
552+
}
553+
```
554+
555+
This ensures reflection-based code continues working.
556+
399557
### `Info.plist` (iOS)
400558

401559
`Info.plist` (Information Property List) is the configuration file for iOS apps. It’s a structured XML file that provides iOS with essential information about your app’s configuration and requirements.
@@ -535,6 +693,34 @@ This enables your app to create, manage, and present passes in Apple Wallet.
535693
You can modify the `Entitlements.plist` file by either [**adding a snippet**](#snippet-placement-for-ios) or [**editing it manually**](#option-2-manual-edit-mode).
536694
:::
537695

696+
### `AppDelegate.swift` (iOS)
697+
698+
The `AppDelegate.swift` file is the entry point for your iOS application. It plays a crucial role in setting up your app’s runtime environment and handling app lifecycle events such as launching, backgrounding, and termination. This file is also where you register Flutter plugins and initialize SDKs like Firebase or Branch.
699+
700+
It’s located at: `ios/Runner/AppDelegate.swift`
701+
702+
**Example: Registering Custom iOS Plugins**
703+
704+
For custom native iOS plugins that aren’t auto-registered, you can manually register them inside `AppDelegate.swift`.
705+
706+
```jsx
707+
override func application(
708+
_ application: UIApplication,
709+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
710+
) -> Bool {
711+
let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
712+
let myPlugin = CustomPlugin()
713+
myPlugin.register(with: controller)
714+
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
715+
}
716+
```
717+
718+
Use this for custom iOS integrations that require manual setup.
719+
720+
:::tip
721+
You can modify the `AppDelegate.swift` file by either [**adding a snippet**](#snippet-placement-for-ios) or [**editing it manually**](#option-2-manual-edit-mode).
722+
:::
723+
538724
### `main.dart` (Flutter)
539725
540726
The `main.dart` file is the entry point of every FlutterFlow app. It is the first file that runs when the app starts and is responsible for initializing the application, configuring dependencies, and defining the root widget. Located in the **`lib/`** directory, `main.dart` contains the `main()` function, which is required for every FlutterFlow app.
@@ -642,77 +828,6 @@ class AppLifecycleObserver with WidgetsBindingObserver {
642828
}
643829
```
644830
645-
### ProGuard File (Android)
646-
647-
The **ProGuard file (`proguard-rules.pro`)** is a configuration file used in Android projects to optimize, shrink, and obfuscate the app’s code. It helps reduce APK or AAB size, improves performance, and protects the app’s code from reverse engineering by making it difficult to decompile.
648-
649-
The ProGuard files allow you to specify rules to keep certain classes or methods (prevent them from being removed or renamed), or to tweak the obfuscation behavior. Located in the **`android/app/proguard-rules.pro`** directory of an Android project, the ProGuard rules are applied when code shrinking is enabled in a release build.
650-
651-
Here are some scenarios where you may need to modify the ProGuard file:
652-
653-
**Example 1: Preventing Issues with Third-Party Libraries**
654-
655-
ProGuard can obfuscate critical libraries, breaking their functionality. To prevent this, you need to keep specific classes used by the library.
656-
657-
```jsx
658-
# Firebase
659-
-keep class com.google.firebase.** { *; }
660-
661-
# Gson (JSON Serialization)
662-
-keep class com.google.gson.** { *; }
663-
-keepattributes *Annotation*
664-
```
665-
666-
This ensures that Firebase and Gson classes are not obfuscated, preventing serialization errors.
667-
668-
**Example 2: Debugging ProGuard Issues**
669-
670-
If your app crashes in release mode but works in debug mode, ProGuard might be removing important classes. To troubleshoot, you can add logging and keep rules.
671-
672-
```jsx
673-
-assumenosideeffects class android.util.Log {
674-
public static *** d(...);
675-
public static *** v(...);
676-
public static *** i(...);
677-
}
678-
```
679-
680-
This removes debug logs in release builds but retains them for troubleshooting.
681-
682-
**Example 3: Improving Security by Removing Debug Information**
683-
684-
Attackers can decompile APKs and view sensitive debug logs. To remove these debug logs, add:
685-
686-
```jsx
687-
-dontwarn android.util.Log
688-
```
689-
690-
691-
**Example 4: Keeping Native Libraries (JNI) Safe**
692-
693-
If your app uses native C/C++ libraries (JNI), ProGuard may mistakenly remove required components. To prevent this:
694-
695-
```jsx
696-
-keep class com.example.native.** { *; }
697-
-keepclassmembers class * {
698-
native <methods>;
699-
}
700-
```
701-
702-
This keeps all native methods intact.
703-
704-
**Example 5: Preventing Issues with Reflection-Based Code**
705-
706-
Some libraries rely on reflection to dynamically call methods, which ProGuard may remove.
707-
708-
```jsx
709-
-keep class * implements android.os.Parcelable { *; }
710-
-keepclassmembers class ** {
711-
@android.webkit.JavascriptInterface <methods>;
712-
}
713-
```
714-
715-
This ensures reflection-based code continues working.
716831
717832
## Best Practices
718833

docs/ff-concepts/adding-customization/custom-code.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ necessary code.
6868
This can significantly speed up the building process and reduce the need for in-depth programming
6969
knowledge, making it especially useful for custom functions and actions.
7070

71-
**Limitation:** The prompts are limited to 100 characters currently.
71+
:::info[Limitation]
72+
Your prompt must be at least 3 words and no more than 500 characters.
73+
:::
7274

7375
<div style={{
7476
position: 'relative',

0 commit comments

Comments
 (0)