π§ Introduction
When building modern apps, you often need to perform complex database operations β like filtering data, calculating values, or combining multiple queries. Writing all this logic directly in your Flutter app can quickly become messy and inefficient.
Thatβs where RPC (Remote Procedure Call) functions in Supabase come in.
π RPC functions allow you to write SQL functions inside your database and call them directly from your app as if they were APIs.
β Why use RPC functions in Supabase?
- Keep business logic inside the database (cleaner architecture)
- Reduce network calls (better performance)
- Improve security (controlled access to data)
- Reuse logic across multiple clients (Flutter, Web, etc.)
π§° Prerequisites
Before we start, make sure you have:
- β A Flutter project set up
- β A Supabase project created
- β Supabase Flutter SDK installed
- β Basic knowledge of SQL (SELECT, WHERE, etc.)
βοΈ Step 1: Create an RPC Function in Supabase
Letβs say we have a tasks table and we want to fetch all completed tasks for a specific user.
ποΈ Example Table: tasks
idtitleuser_idis_completed1Task A101true2Task B101false
π§Ύ SQL Function
Go to Supabase Dashboard β SQL Editor, and run:
create or replace function get_completed_tasks(p_user_id uuid)
returns table (
id uuid,
title text,
is_completed boolean
)
language sql
as $$
select id, title, is_completed
from tasks
where user_id = p_user_id
and is_completed = true;
$$;
π Explanation (Simple)
- create or replace function β creates the RPC function
- p_user_id β input parameter
- returns table β defines output structure
- select ... β actual query logic
π§ͺ Step 2: Test the Function in Supabase
Before using it in Flutter, test it.
Run this in SQL Editor:
select * from get_completed_tasks('your-user-id-here');
β
Expected Output
You should see only completed tasks for that user.
π± Step 3: Call RPC Function in Flutter
Now letβs call this function from your Flutter app.
π¦ Add Supabase Dependency
dependencies:
supabase_flutter: latest_version
β‘ Initialize Supabase
await Supabase.initialize(
url: 'YOUR_SUPABASE_URL',
anonKey: 'YOUR_SUPABASE_ANON_KEY',
);
π₯ Call RPC Function
final supabase = Supabase.instance.client;
Future<List<dynamic>> getCompletedTasks(String userId) async {
final response = await supabase.rpc(
'get_completed_tasks',
params: {'p_user_id': userId},
);
return response;
}
π§ Explanation
- rpc() β calls Supabase function
- 'get_completed_tasks' β function name
- params β must match SQL parameter names π₯οΈ Use in UI
FutureBuilder(
future: getCompletedTasks(userId),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
final tasks = snapshot.data as List;
return ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
final task = tasks[index];
return ListTile(
title: Text(task['title']),
subtitle: Text("Completed"),
);
},
);
},
);
π Real-World Use Case
Letβs say youβre building a Task Management App (like your current Flutter project π).
Instead of:
β Fetching all tasks
β Filtering in Flutter
You can:
β
Use RPC to fetch only required data
β
Improve performance and reduce app logic
π‘ Other Use Cases
- Calculating total revenue
- Fetching user-specific dashboards
- Complex joins across tables
- Role-based data filtering β οΈ Common Mistakes β 1. Parameter Name Mismatch
params: {'userId': userId} // WRONG
β Must match SQL:
p_user_id
β 2. Forgetting Permissions (RLS)
If Row Level Security (RLS) is enabled:
π Make sure policies allow access
β 3. Returning Wrong Data Type
If your function returns:
returns json
Then handle it properly in Flutter.
β 4. Not Testing in SQL First
Always test in Supabase before calling from Flutter.
π§ Best Practices
β
Keep functions simple and focused
One function = one responsibility
β
Use meaningful names
get_user_tasks β
fetch_data β
β
Secure with RLS policies
Donβt expose sensitive data
β
Use indexes for performance
Especially for large datasets
β
Prefer SQL functions over multiple API calls
Cleaner + faster
π Conclusion
RPC functions in Supabase are a powerful way to move logic closer to your database, making your Flutter apps:
- β‘ Faster
- π§Ή Cleaner
- π More secure By following this step-by-step guide, you can now:
β Create SQL functions
β Test them in Supabase
β Call them seamlessly from Flutter
π Next Steps
Add pagination to your RPC functions
Use PostgreSQL joins inside functions
Explore Edge Functions vs RPC
Build reusable backend logic library
If youβre building scalable Flutter apps with Supabase, mastering RPC is a game changer π₯

Top comments (0)