Backend-as-a-Service promised to remove servers from your life. It delivered — and replaced them with a quieter problem: Firestore Security Rules and Supabase Row Level Security are now the only thing standing between your data and the open internet. Most teams get them wrong not because they are careless, but because the rules language is deceptively simple. An LLM will not fix that for you, but a well-shaped prompt will force it to expose the holes before an attacker does.
This roundup is a working set of prompts for schema design, rule authoring, query optimisation, and auth migration on Firebase and Supabase. Each one includes the reasoning behind it and a real usage example. The goal is not to let the model write your backend — it is to make the model your adversarial reviewer.
Why BaaS Rules Break in Production
A typical failure: a developer writes allow read, write: if request.auth != null; on a users collection. It passes every test because the test user is always the owner. In production, any authenticated user can read every other user's email and overwrite their profile. The rule is syntactically valid and semantically catastrophic.
The second failure is performance. Firestore charges per document read, and a query without a composite index either fails outright or silently scans. Supabase RLS policies that call a function per row turn a 10 ms query into a 2-second one under load. Neither problem shows up in development with ten documents.
Prompt 1: Schema Design With Access Patterns First
Most schema prompts fail because they ask for entities, not queries. Firestore has no joins, so the schema must be derived from the read patterns. This prompt forces that order.
Prompt:
You are a Firestore data modeller. Given these access patterns:
- List the 20 most recent posts in a group, paginated
- Show a user's unread notification count
- Fetch a single post with its author's display name
Design the collection structure. For each collection, list:
1. Document ID strategy (auto-ID, composite key, or UID)
2. Fields and types
3. Which queries require composite indexes
4. Which data is denormalised and what breaks when it changes
Do not propose subcollections unless a query requires them.
Example use: For a community app, the model will typically propose groups/{groupId}/posts/{postId} with a denormalised authorName on each post. That is correct for read speed but breaks when a user renames themselves. The prompt's fourth question surfaces that cost before you ship.
Prompt 2: Adversarial Firestore Security Rules Review
This is the prompt that pays for itself. Instead of asking the LLM to write rules, give it your existing rules and ask it to break them.
Prompt:
Here are my Firestore Security Rules:
[paste rules]
Act as an attacker with a valid authenticated account. List every
document I can read or write that I should not be able to. For each
finding, show the exact request path and the rule that permits it.
Then propose a corrected rule and a test case using the
Firebase Emulator Suite.
Example finding: The model will flag rules like allow write: if request.auth.uid == resource.data.ownerId; — this permits the owner to change ownerId itself, transferring the document to another user. The fix is to split create and update, and pin immutable fields:
allow update: if request.auth.uid == resource.data.ownerId
&& request.resource.data.ownerId == resource.data.ownerId;
That single line is the difference between a profile edit and an account takeover.
Prompt 3: Supabase RLS Policies That Do Not Kill Performance
Supabase RLS is powerful and easy to make slow. A policy that calls auth.uid() is fine; a policy that joins to another table per row is not. This prompt separates correctness from cost.
Prompt:
Write RLS policies for these tables: [schema]. Requirements:
- Users read only their own rows in `profiles`
- Members of an `org` read all rows in `projects` where org_id matches
- Service role bypasses RLS
For each policy, state the USING and WITH CHECK clauses separately,
and flag any policy that would cause a sequential scan on a table
expected to exceed 100k rows. Suggest the index needed.
Example: For projects, the model produces:
create policy "org members read projects"
on projects for select
using ( org_id in (
select org_id from memberships where user_id = auth.uid()
));
Then it flags that the subquery runs per row unless memberships(user_id) is indexed. Adding that index is a one-line migration that turns a table scan into an index lookup.
Prompt 4: Composite Index Generation From Query Logs
Firestore throws a FAILED_PRECONDITION error when a composite index is missing, but the error message is cryptic. Paste it in.
Prompt:
This Firestore query fails with FAILED_PRECONDITION:
[paste error]
The query is: [paste query]
Give me the exact composite index definition in firestore.indexes.json
format, and explain why the field order matters.
Example: A query where('status','==','open').orderBy('createdAt','desc') needs an index with status ascending and createdAt descending. Reversing the order makes the index useless. The model will explain that Firestore can serve an equality filter from any position but requires the orderBy field last — a rule most developers learn only after a production outage.
Prompt 5: Auth Provider Migration Checklist
Moving from Firebase Auth to Supabase Auth (or the reverse) is where user data leaks. Password hashes are not portable; sessions are not portable.
Prompt:
I am migrating users from Firebase Auth to Supabase Auth.
Produce a step-by-step plan that:
1. Preserves user UIDs or maps old to new
2. Handles users who have not logged in since migration
3. Avoids downtime for active sessions
4. Lists what cannot be migrated and the fallback for each item
Flag any step where user data could be exposed.
Example output: The model will correctly note that Firebase password hashes use a modified scrypt and cannot be imported directly into Supabase's bcrypt-based store. The practical fallback is a forced password reset on first login, triggered by a custom claim. Without this prompt, teams discover the problem after cutover.
When Firebase, When Supabase
| Criterion | Firebase | Supabase |
|---|---|---|
| Real-time sync out of the box | Yes | Via Realtime, less mature |
| SQL and joins | No | Yes |
| Pricing model | Per read/write | Per compute/storage |
| Rule language | Custom, limited | SQL policies |
| Best for | Mobile apps with offline needs | Web apps with relational data |
If your app is read-heavy and offline-first, Firebase's local cache is hard to beat. If your data is relational and your team knows SQL, Supabase removes a layer of translation. The LLM prompts above work for both, but the failure modes differ: Firestore punishes bad schema with cost, Supabase punishes bad RLS with latency.
For related reading on backend reliability and query design, see our breakdown of Go for backend with gRPC and the practical pitfalls of AI agents in production.
The Takeaway
An LLM will not secure your BaaS backend for you. But it will read your rules the way an attacker does, generate the composite index you forgot, and flag the migration step that leaks passwords. The pattern is consistent: give the model the access patterns first, ask it to break what exists, and demand a test case for every fix. That turns a vague sense of security into a checklist you can actually run.