# Supabase for FDEs: build a demo backend with sign-in, Postgres and Edge Functions in one afternoon

> Building a backend for a customer in an afternoon is not hard. The hard part is making sure each user sees only their own data before the customer tries it.

Original: https://fdetimes.net/en/tools/supabase-backend-demo-auth-postgres-edge-functions/

One missing line of SQL is enough for your demo to expose every user's data. Or to show a blank screen at the exact moment the customer signs in to try it. With Supabase, both outcomes trace back to the same place: Row Level Security.

That is why this article treats Supabase as a working tool for FDEs, not just a convenience for side projects. When a customer asks "can you show us something this afternoon?", you need a backend with sign-in, a real database and a little server-side logic. You also have to be sure that user A cannot see user B's data.

## Why one afternoon is enough

Supabase describes itself as a development platform built on Postgres. Each project gets its own Postgres database for a web, mobile or AI application. The team says it is rebuilding Firebase's features with enterprise-grade open-source tools, and the code is released under the Apache-2.0 licence.

Underneath sits PostgreSQL, a database whose origins go back to 1986 and which has been ACID-compliant since 2001. When the demo becomes a pilot, the customer's engineers will not have to learn an unfamiliar database.

The most valuable detail for an FDE is that Auth uses the project's own Postgres database. User records live in a separate schema, right next to the business data.

Auth supports many methods, including social sign-in and phone sign-in through third-party providers. Because users and data sit in the same place, there is one less system to wire together.

## Example: drivers see only their own deliveries

Imagine the customer is a delivery company. They want each driver, once signed in, to see only the deliveries assigned to them. The core of the demo fits in one table and one policy:

```sql
create table deliveries (
  id bigint generated always as identity primary key,
  driver_id uuid not null references auth.users(id),
  address text not null,
  status text not null default 'pending'
);

alter table deliveries enable row level security;

create policy "driver sees own deliveries"
  on deliveries for select
  using (auth.uid() = driver_id);
```

According to Supabase's documentation, when combined with RLS policies, the sign-in token restricts database access down to individual rows. A driver who sends their token gets back only the rows whose `driver_id` matches them. You do not need to write an extra authorisation layer in the frontend.

Next, the customer wants a delivery time estimate. Edge Functions are server-side TypeScript functions, distributed globally at the edge, close to users. They run on Deno, an open-source runtime with TypeScript built in:

```ts
Deno.serve(async (req) => {
  const { stops } = await req.json();
  const minutes = stops.length * 12; // demo assumption: 12 minutes per stop
  return new Response(JSON.stringify({ eta_minutes: minutes }), {
    headers: { "Content-Type": "application/json" },
  });
});
```

You can deploy the function from the Dashboard, the CLI or MCP. From a terminal, run `supabase functions deploy eta`. The formula is deliberately simple: at a first meeting, the customer needs to see the whole flow working more than a clever algorithm.

## Two ways RLS breaks a demo

**Key point:** Before the customer tries it, check who can see which rows.

The milder failure is enabling RLS and forgetting to write a policy. Supabase's documentation is explicit: once RLS is enabled, the API returns no data for the publishable key until you create a policy. In the example above, drop the `create policy` statement and a driver signs in successfully but sees 0 deliveries, and the customer will think the system is broken.

The more serious failure is forgetting to enable RLS. A table in an exposed schema without RLS can be read and written by any role with a grant on it. If the demo runs on the customer's real data, this is a security incident, not a display bug.

So treat the final check as mandatory. Create two test accounts, assign each a few deliveries, then sign in with each in turn. Each account must see exactly its own share: nothing more, nothing missing.

## What does the Free plan give you?

The Free plan includes a 500 MB database on a shared CPU with 500 MB of RAM, and 50,000 monthly active users. For a demo, that is more than enough. The limits worth watching are elsewhere.

Free projects are paused after 1 week of inactivity, and each account can have at most 2 active projects. Say you demo on a Monday and the follow-up meeting is ten days later: by then the project has been paused. Reopen it the day before the meeting, and move to the paid Pro plan when the demo becomes a pilot.

Remember too that Edge Functions are written in TypeScript. If the customer's existing logic is in another language, you will have to port it to TypeScript or run that part somewhere else. Ask about this during discovery.

## What to learn first

Start with SQL and writing RLS policies, because most of a demo's risk lives there. Then learn the CLI. It runs Supabase services on your own machine, manages hosted projects from the terminal, and supports migrations and declarative schemas, so you can rebuild the whole demo in the customer's own project.

If you are aiming for an FDE role, you can turn the delivery exercise above into a portfolio piece. On your CV, do not just write "knows Supabase". Describe the result: you built a demo with sign-in, row-level access control with RLS and a server-side function, and say how long it took.

The customer will not remember which tools you used. They will remember the moment two drivers signed in side by side and each saw only their own deliveries.

**Try this week:**

- Create a Free project, build the deliveries table from the example, enable RLS, then sign in with two test accounts to confirm each sees only its own rows.
- Run Supabase locally with the CLI, save the schema as a migration, then rebuild the whole demo on an empty project and time how long it takes.
- Write a small Edge Function in TypeScript, deploy it with the CLI, then call it from the terminal.

## Sources

- [GitHub - supabase/supabase: The Postgres development platform.](https://github.com/supabase/supabase)

- [Edge Functions | Supabase Docs](https://supabase.com/docs/guides/functions)

- [Auth | Supabase Docs](https://supabase.com/docs/guides/auth)

- [Row Level Security | Supabase Docs](https://supabase.com/docs/guides/database/postgres/row-level-security)

- [Supabase Pricing](https://supabase.com/pricing)

- [Local Development & CLI | Supabase Docs](https://supabase.com/docs/guides/local-development)

- [PostgreSQL: About](https://www.postgresql.org/about/)

- [Deno, the drop-in JavaScript runtime for Node developers](https://deno.com/)
