Supabase Database Functions
Supabase database functions are reusable PostgreSQL functions that run inside your Supabase database. FlutterFlow can call these functions through a Remote Procedure Call (RPC), pass values to their arguments, and use the returned data in your app.
Database functions are useful for calculations, aggregated results, complex queries, and operations that are difficult to perform with a standard Supabase query. For example, the following app uses a database function to calculate and display the completion percentage for each project.
- Complete the Supabase setup and connect your project to FlutterFlow.
- For this example, create the
taskstable and the columns used by the function. - Configure suitable database permissions and Row Level Security (RLS) policies for the data the function accesses.
When to Use a Database Function
Use a database function when you need to:
- Return data from complex queries or multiple related tables.
- Run a calculation or aggregation close to the data.
- Reuse the same database logic in different parts of your app.
- Perform multiple related database operations together.
For straightforward row operations, such as inserting, updating, deleting, or querying rows, use Supabase Database Actions. Use a Supabase Edge Function when the operation needs server-side TypeScript, secrets, or calls to external services.
1. Create a Database Function
You can create a database function from the Supabase Dashboard using the SQL Editor, as described in the Supabase database functions guide.
The following get_project_progress function reads the task counts for each project and returns each project's completion percentage:
create or replace function public.get_project_progress()
returns table (
id text,
project_name text,
number_tasks bigint,
completed_tasks bigint,
completion_percentage numeric
)
language sql
security invoker
as $$
select
t.id,
t.project_name,
t.number_tasks,
t.completed_tasks,
case
when coalesce(t.number_tasks, 0) = 0 then 0
else round(
(coalesce(t.completed_tasks, 0)::numeric / t.number_tasks) * 100,
2
)
end as completion_percentage
from public.tasks t;
$$;
To create the database function in Supabase:
- Open your project in the Supabase Dashboard.
- Go to SQL Editor and write your SQL query.
- Click Run and review the returned rows.
- Go to Database > Functions to verify that your function is listed.
Use security invoker unless the function specifically needs to run with the function creator's permissions. With invoker security, the function runs using the permissions of the signed-in user. Also review who has permission to execute the function and protect the tables it accesses with RLS. See the Supabase database functions guide and API security guide.
2. Import Database Functions into FlutterFlow
After creating or changing a function in Supabase, refresh the schema in FlutterFlow:
- Open Settings and Integrations > Supabase.
- Confirm that the correct Supabase project is connected.
- Click Update Schema.
This fetches the latest database definitions and makes compatible PostgreSQL functions available as Supabase RPC actions. Repeat this step whenever you change a function's name, arguments, or return type.
3. Call a Database Function
You can call an imported database function using any appropriate action trigger. For example, call a function on page load to retrieve the latest progress when the page opens.
- Select the widget or page where you want to call the function and open the Action Flow Editor.
- Select an existing trigger or add a new one.
- Select a Supabase RPC action.
- If the function accepts arguments, set each one using a specific value or a variable.
- Enter an Action Output Variable Name so you can use the returned data in later actions.
4. Use the Function Output
The data available from the action output is determined by the function's declared return type. A function can return a single value, one object, or multiple rows. For example, get_project_progress uses returns table (...) to declare a tabular result with columns for the project name, task counts, and calculated completion percentage:
returns table (
id text,
project_name text,
number_tasks bigint,
completed_tasks bigint,
completion_percentage numeric
)
Here, returns table defines the columns returned by the function. It does not create or refer to a physical table in Supabase. Supabase returns the generated rows as a JSON array, with each row represented as an object:
[
{
"id": "c45a5311-3899-437b-9be5-72b4b342751a",
"project_name": "Mobile App Release - Discovery",
"number_tasks": 13,
"completed_tasks": 5,
"completion_percentage": 38.46
}
]
To use these rows as structured data, create a Custom Data Type, such as ProjectProgress. Its field names must exactly match the JSON field names, including capitalization and underscores:
| JSON field | Custom Data Type field | FlutterFlow data type |
|---|---|---|
id | id | String |
project_name | project_name | String |
number_tasks | number_tasks | Integer |
completed_tasks | completed_tasks | Integer |
completion_percentage | completion_percentage | Double |
Because this function returns multiple rows, create a page-state variable that holds a list of ProjectProgress values. In an Update Page State action, use the RPC Action Output as the source and map the returned JSON array to that variable. You can then use the structured list in widgets and later actions on the page.
You do not need to save the result in page state when only subsequent actions need it. In that case, use the RPC result directly from Action Outputs.
FAQs
Why doesn't my database function appear in FlutterFlow?
Confirm that the function exists in the connected Supabase project, then click Update Schema. If it still does not appear, review the function's schema, arguments, and return type.
Why does my app receive a permission error when calling a function?
Check the function's execute privileges and the permissions for every table it accesses. For a security invoker function, the calling user must be allowed to access the underlying data, including through applicable RLS policies.
Why does the action show old arguments or output fields?
Click Update Schema after changing the function. Then reopen the Supabase RPC action and verify its arguments, output variable, and any widgets or state variables that use the result.