O login funcionou normalmente, mas a tela mostra pedidos, perfis ou notas de outros usuários misturados com os seus. Isso é um vazamento de dados, então é o bug de maior prioridade para corrigir. A causa quase sempre é a mesma: o servidor não filtra por "de quem é esta linha" e envia tudo para o navegador.

Does this match your symptom?

  • Você está logado na sua própria conta, mas a lista contém dados de outras pessoas
  • Trocar o id numérico na URL abre a página de detalhes de outra pessoa
  • No começo estava tudo bem, mas com mais usuários eles passaram a ver os dados uns dos outros

Why it happens

Três causas comuns para quem não é desenvolvedor:

  1. O RLS (Row Level Security) do Supabase está desativado — as tabelas do schema public podem ser lidas por completo pela API, a menos que o RLS esteja ativado.
  2. A consulta não tem a condição "só as minhas" — falta um WHERE user_id = ..., ou as regras do Firebase ficaram em modo de teste (if true).
  3. Filtrar só no React (lado do cliente) — todas as linhas, inclusive as de outras pessoas, já chegaram ao navegador e você apenas as escondeu na tela. Abra a aba Network do DevTools e estão todas lá. This is not security.

30-second diagnosis

No navegador: F12 → aba Network → clique na requisição que carrega a lista → Response.

Se a resposta JSON contiver linhas de outros usuários, o servidor está enviando elas, então você precisa corrigir no servidor (abaixo). Editar só o React não resolve.

Fix A — If you use Supabase

  1. Confirme que a tabela tem uma coluna user_id (se faltar, adicione uma coluna uuid que guarde o id de auth.users).
  2. Rode isto no SQL Editor do painel (troque todos pelo nome da sua tabela):
sql

-- 1) Turn RLS on
alter table todos enable row level security;

-- 2) Auto-fill the owner id on new rows (optional)
alter table todos alter column user_id set default auth.uid();

-- 3) Read only my rows
create policy "select own rows" on todos
  for select to authenticated
  using ( auth.uid() = user_id );

-- 4) Insert only as myself
create policy "insert own rows" on todos
  for insert to authenticated
  with check ( auth.uid() = user_id );

-- 5) Update only my rows
create policy "update own rows" on todos
  for update to authenticated
  using ( auth.uid() = user_id )
  with check ( auth.uid() = user_id );

-- 6) Delete only my rows
create policy "delete own rows" on todos
  for delete to authenticated
  using ( auth.uid() = user_id );
  1. Salve, faça login com outra conta e teste de novo. Agora as linhas dos outros usuários somem completamente da resposta.

> Observação: depois que o RLS é ativado, nada fica visível até você adicionar políticas — isso é esperado. As políticas acima são o que restaura o "só as minhas".

Fix B — If you use Firebase (Firestore)

No console do Firebase, vá em Firestore Database → Rules, substitua a regra de modo de teste (allow read, write: if true;) pela regra de dono e clique em Publish:

text

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /todos/{docId} {
      allow read, update, delete: if request.auth != null
                                  && request.auth.uid == resource.data.uid;
      allow create: if request.auth != null
                    && request.auth.uid == request.resource.data.uid;
    }
  }
}

Você também precisa filtrar a consulta para os seus próprios dados. As regras do Firestore não são filtros: uma consulta ampla demais não é cortada silenciosamente — ela é rejeitada de vez.

js

import { collection, query, where, getDocs } from "firebase/firestore";

const q = query(
  collection(db, "todos"),
  where("uid", "==", auth.currentUser.uid)   // only mine
);
const snap = await getDocs(q);

(Se os seus dados são indexados pelo id do usuário no caminho do documento, use match /users/{userId} com allow read, write: if request.auth.uid == userId;.)

Fix C — If you have your own backend (Express, etc.)

Force a consulta com o userId obtido da sessão/token de login. Never trust an id sent by the client — ele pode ser trocado.

js

// use the value from the session only
const rows = await db.query(
  "select * from todos where user_id = $1",
  [req.user.id]   // NOT req.body / req.query id
);

The one line to remember

Um filtro no lado do cliente (React) serve para organizar a tela, não para segurança. Só o servidor (RLS, regras de segurança, WHERE) de fato estanca o vazamento.