Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/ff-concepts/file-handling/displaying-media.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ You can also access media files within your app that are stored temporarily in y

![dm-local-upload.avif](imgs/dm-local-upload.avif)

:::info[Image Uploads via WebView May Fail on Real Devices]
Image uploads inside a WebView may fail on physical devices even if they work in Run/Test mode. This happens because FlutterFlow doesn't auto-request Photo Library permissions at runtime.

To fix this:
- Enable Photo Library in Settings > Permissions.
- Add a Get Permission action to request access before uploading.
- Reinstall the app on the device after adding the permission.

If permissions aren’t granted, the upload will silently fail. Users may have to manually allow access via their device’s app settings.
:::

## AudioPlayer

The **AudioPlayer** widget allows you to integrate audio playback into your apps. You can play audio from both uploaded assets and external URLs. Refer to the [**Displaying Media**](#media-types) section for more details on accessing media.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
keywords: ['firebase', 'users', 'group']
slug: /troubleshooting/notifications/send-notifications-to-user-groups
title: Send Notifications to Specific User Groups
---

# Send Notifications to Specific User Groups

This guide explains how to send push notifications to a specific group of users in your FlutterFlow project based on an attribute such as `isPremium`. This is useful when you want to automatically notify a user segment whenever a new document (e.g., a post) is created.

You can review the full working example in this **[sample FlutterFlow project](https://app.flutterflow.io/project/auto-notification-2bm5hz)**.

:::info[Prerequisites]
- Your project must be connected to Firebase.
- Push notifications must be enabled and deployed.
- The project must be on the **Blaze** plan.
- The `firebase@flutterflow.io` service account must have proper permissions.
:::

**Configure the Project:**

1. Ensure Firebase is set up correctly in your FlutterFlow project.
**See**: **[Firebase Integration Guide](/integrations/firebase/connect-to-firebase/)**

2. Make sure push notifications are enabled and deployed from **Settings > Notifications**.

3. Add a user attribute (e.g., `isPremium`) in your **users** collection to filter recipients.

## Create the Notification Workflow

1. Select the **Submit** button or trigger event.
2. Add a **Backend Query** action:
- **Query Type**: `Query Collection`
- **Collection**: `users`
- **Query Mode**: `List of Documents`

3. Add a **Create Document** action to create the post or data entry.

4. Add a **Trigger Notification** action:
- Set the notification `title`, `message`, and `initial page`.

5. In the **Recipient** section:
- Click `unset` to select the recipient source.
- Choose **User Document**.
- Select **Filter List Items**.

:::note
To filter a specific group, such as premium users, ensure the users collection includes a boolean attribute like `isPremium`.
:::

6. In the filter condition popup:
- Select **Items in list**
- Set **Document Property** to `isPremium`
- Choose **is equal to** → `True`

7. Click **Confirm** to save the condition.
8. Back in the recipient popup, select **Map List Items**.
9. Click `unset`, then select **Reference** under Document Properties.
10. Click **Confirm** in all dialogs to complete the action chain.

The notification will be automatically triggered whenever a new document is created, and it will be sent only to users that match the filter condition.
48 changes: 48 additions & 0 deletions docs/ff-integrations/authentication/firebase-auth/auth-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ tags: [Auth Actions, Authentication, Firebase]
sidebar_position: 1
keywords: [FlutterFlow, Auth Actions, Authentication, Firebase]
---

# Common Auth Actions

Here's a list of common authentication actions:
Expand All @@ -22,6 +23,53 @@ Follow the steps below to add this action:

![logout](../imgs/logout-action.png)

## Login [Action]

The Login action allows users to authenticate and gain access to your app. Login behavior can differ based on the provider you configure (e.g., email/password, Google, Apple, phone number). Each provider has its own setup, but they all share the same underlying action to sign in users.

You typically add the login action to a button (e.g., "Login" or "Sign In") that collects user credentials via TextFields or third-party authentication triggers.

**Supported Providers**
The following authentication providers can be used with the **Login [Action]**. Each link will guide you to the setup and usage details:

- **[Email Login](/integrations/authentication/firebase/email-login)**
- **[Google OAuth Login](/integrations/authentication/firebase/google-oauth-login#enable-google-sign-in-provider-in-firebase)**
- **[Apple Login (Supabase)](/integrations/authentication/supabase/apple)**
- **[Phone Login](/integrations/authentication/firebase/phone)**
- **[Facebook Login](/integrations/authentication/firebase/facebook)**
- **[Anonymous Login](/integrations/authentication/firebase/anonymous-login)**
- **[GitHub Login](/integrations/authentication/firebase/github#2-adding-github-login-action)**
- **[JWT Token Login](/integrations/authentication/firebase/jwt-auth#1-add-login-api)**
- **[Custom Auth Login](/integrations/authentication/custom-authentication)**
- **[Supabase Auth Login](/integrations/authentication/supabase/initial-setup)**

:::note
Each provider requires its own initial setup (e.g., enabling in Firebase or Supabase, configuring OAuth keys). Once configured, all providers use the same **Login [Action]** to sign in the user.
:::

## Handling Invalid Login Credentials

When a user enters incorrect login credentials, FlutterFlow automatically displays a `SnackBar` with an error message. This helps users understand why their login attempt failed without needing custom logic.

![](../imgs/20250430121519975010.gif)

When the **Login Action** fails, a `SnackBar` is shown with the relevant error (e.g., “No user found” or “Wrong password”). This message appears automatically during runtime; no additional configuration is required.

:::tip
There is no need to manually add alert dialogs for failed login attempts. FlutterFlow handles `SnackBar` display automatically when authentication fails.
:::

**Customize the SnackBar (Optional)**

1. Select the **Login Action** from your button or trigger.
2. In the **Actions tab**, open the **Action Output** section.
3. Use conditional logic to check the error message.
4. Display a custom `SnackBar` or navigate based on the message content.

:::note
To customize the `SnackBar` further, use the **Action Output** and attach additional logic based on the error string.
:::

## Reset Password

With Firebase Authentication, there are two ways you can allow users to reset their password in your FlutterFlow app:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
217 changes: 217 additions & 0 deletions docs/ff-integrations/maps/geocoding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
---
slug: /integrations/maps/geocoding
title: Geocoding in FlutterFlow
keywords: ['geocoding', 'reverse geocoding', 'maps', 'location', 'address']
---

# Geocoding in FlutterFlow

**Geocoding** is the process of converting between human-readable addresses (like “1600 Amphitheatre Parkway, Mountain View, CA”) and geographic coordinates (latitude and longitude).

FlutterFlow supports geocoding through **custom API calls** and **custom code actions**, giving you flexibility to choose the approach that works best for your app.

**Types of Geocoding**

There are two common types of geocoding:

1. **Forward Geocoding**
Converting an address into geographic coordinates.
*Example:* `"Paris, France"` → `(48.8566, 2.3522)`

2. **Reverse Geocoding**
Converting geographic coordinates into an address.
*Example:* `(37.4221, -122.0841)` → `"1600 Amphitheatre Parkway, Mountain View, CA"`

**Approaches in FlutterFlow**

You can implement geocoding in FlutterFlow in two main ways:

1. **Google Maps Geocoding API**

- Uses the official Google Maps API for reliable, global geocoding.
- Requires a Google Cloud project and API key.
- Works via a standard API Call in FlutterFlow.
- Best for:
- Apps with existing Google Maps integrations.
- Large-scale or high-accuracy location services.

See: **[Google Maps Geocoding API Documentation](https://developers.google.com/maps/documentation/geocoding)**

Example: Forward Geocoding API Call

**Endpoint:**
```js
GET https://maps.googleapis.com/maps/api/geocode/json?address=Paris,France&key=YOUR_API_KEY
```

**Sample Response**
```json
{
"results": [
{
"formatted_address": "Paris, France",
"geometry": {
"location": {
"lat": 48.856614,
"lng": 2.3522219
}
}
}
],
"status": "OK"
}

**FlutterFlow API Call Setup**

- Method: GET
- URL: `https://maps.googleapis.com/maps/api/geocode/json`
- Query Parameters:
- address → `Paris`,`France` (or variable)
- `key` → your Google Maps API key

2. **`geocoding` Dart Package (Custom Code)**

- Uses Flutter’s [`geocoding`](https://pub.dev/packages/geocoding) package for native geocoding.
- Works entirely offline for some lookups (depending on platform and data availability).
- Implemented via a custom action in FlutterFlow.
- Best for:
- Apps that don’t want to rely on external APIs.
- Simpler geocoding needs.

**Example: Forward Geocoding with geocoding package**

```dart
import 'package:geocoding/geocoding.dart';
Future<void> getCoordinatesFromAddress(String address) async {
try {
List<Location> locations = await locationFromAddress(address);
if (locations.isNotEmpty) {
print('Latitude: ${locations.first.latitude}');
print('Longitude: ${locations.first.longitude}');
}
} catch (e) {
print('Error: $e');
}
}
```
**Example: Reverse Geocoding with geocoding package**

```dart
import 'package:geocoding/geocoding.dart';
Future<void> getAddressFromCoordinates(double lat, double lng) async {
try {
List<Placemark> placemarks = await placemarkFromCoordinates(lat, lng);
if (placemarks.isNotEmpty) {
final place = placemarks.first;
print('${place.street}, ${place.locality}, ${place.country}');
}
} catch (e) {
print('Error: $e');
}
}
```

## Step-by-step guide for reverse geocoding a device’s coordinates.

This guide focuses on **reverse geocoding**—turning a device’s latitude and longitude into a readable address (such as city or street name).

You can achieve this in FlutterFlow using either:

- **The Google Maps Geocoding API** (via API Calls)
- **The `geocoding` Dart package** (via a Custom Action)

Explore a live example in this **[FlutterFlow sample project](https://app.flutterflow.io/project/geo-track-rvndye)**.

**Option 1: Using the Google Maps API**

1. **Enable the Geocoding API**

1. Go to the [Google Cloud Console](https://console.cloud.google.com/).
2. Select your project.
3. Search for and enable the **Geocoding API**.

![](imgs/20250430121231440026.gif)

2. **Add API Key to App State**

1. Go to **App State > Local State** in FlutterFlow.
2. Add a new variable:
- `apiKey` → Type: `String`
3. Paste your Geocoding API key as the default value.

![](imgs/20250430121231812590.png)

3. **Create the API Call**

1. Navigate to **API Calls** in FlutterFlow.
2. Create a new API call with the following configuration:

- **Base URL**:
```js
https://maps.googleapis.com/maps/api/geocode/json
```
- **Method**: `GET`

3. Under **Variables**, add:
- `latlng` → Type: `String`
- `apiKey` → Type: `String`

![](imgs/20250430121232082585.png)

4. Create a Custom Function (LatLng → String)

Create a custom function that accepts a `LatLng` value (device location) and returns a string in `"latitude,longitude"` format.

This will be used to populate the `latlng` variable in your API call.

![](imgs/20250430121232452872.png)

5. **Run the API and Display the Result**

1. Add a button or trigger to run the API call.
2. Pass the following:
- `latlng`: From the custom function.
- `apiKey`: From local state.
3. From the API response, extract the address using a **JSON Path**.

Example JSON Path for city name:
```json
$.results[0].address_components[1].long_name
```
4. Bind the extracted value to a `Text` widget.

**Option 2: Using the `geocoding` Dart Package**

If you prefer to use Flutter's native functionality, you can achieve the same result using the geocoding Dart package in a custom action.

1. **Add the Package**
Add the dependency to your project’s pubspec.yaml file:

```js
dependencies:
geocoding: ^2.1.0
```

2. **Create a Custom Action**
- Create a new custom action.
- Add a parameter: LatLng location.
3. Use the geocoding package to convert the coordinates into a readable address.

Sample code:

```js
import 'package:geocoding/geocoding.dart';

Future<String> getAddressFromLocation(LatLng location) async {
final placemarks = await placemarkFromCoordinates(location.latitude, location.longitude);
final place = placemarks.first;
return '${place.locality}, ${place.country}';
}

```
4. Return the result and bind it to a Text widget.


:::tip
If your app already uses Google Maps for displaying locations, the Google API method will be the most seamless. If you want a code-based approach that avoids API calls, the `geocoding` package is a good alternative.
:::
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions docs/generated-code/ff-app-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,28 @@ These functions are automatically generated to provide a convenient and consiste
:::info[How to create App State variables]
To learn more about creating and using App State variables in FlutterFlow's UI, check out the[ **App State**](../resources/data-representation/app-state.md) guide.
:::

**Practical Example: Using Persisted App State for Onboarding**

You can use Persisted App State variables to control access to certain parts of your app until specific steps are completed.

For example, you might want to ensure users complete an onboarding flow before they can access the home screen or checkout page.

1. **Create a Boolean Variable**

- Go to App Settings > State Management > Persisted Values.
- Add a boolean variable, e.g., `hasCompletedOnboarding`, and set its default value to false.

2. **Update After Onboarding**

- On the final screen of the onboarding flow, add an Update Persisted Value action.
- Set `hasCompletedOnboarding` to `true` when the user finishes onboarding.

3. **Add Conditional Navigation**

- On the target page (e.g., Home), add a Page Load action.
- Create a Conditional Action:
- If `hasCompletedOnboarding == false` → Navigate to the onboarding page.

Use Local State for checks that only apply during the current session.
Use Persisted App State for checks that should work across multiple sessions.
1 change: 0 additions & 1 deletion docs/generated-code/state-mgmt-gen-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ For the **iOS** platform, it uses the [**KeyChain**](https://developer.apple.com
In the case of the **Web**, it uses the [**Web Cryptography**](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) (Web Crypto) API.
:::


## Global State

Global state variables are pieces of information related to the device that are accessible throughout the FlutterFlow app.
Expand Down
Loading