Supabase fornece um banco de dados PostgreSQL, autenticação e assinaturas em tempo real como um backend gerenciado — combinando perfeitamente comPróximo.js para criar aplicativos full-stack em tempo real rapidamente. Este guia cria um aplicativo em tempo real, desde o banco de dados até a implantação.
📋 Table of Contents
Por que Next.js + Supabase?
- Backend completo sem construir um: Banco de dados, autenticação, armazenamento e tempo real prontos para uso
- PostgreSQL real: Não é um banco de dados proprietário — SQL padrão que você pode consultar diretamente
- Assinaturas em tempo real: Ouça as alterações do banco de dados ao vivo com o mínimo de código
- Autenticação integrada: Email, OAuth, links mágicos — nenhuma infraestrutura de autenticação para construir
- Código aberto: Auto-hospedável, evitando a dependência de fornecedores
Configuração
npx create-next-app@latest my-app
cd my-app
npm install @supabase/supabase-js @supabase/ssr
# Create a project at supabase.com, then add to .env.local
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
Configuração do cliente Supabase
// lib/supabase.js
import { createClient } from '@supabase/supabase-js';
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);
Crie uma Tabela (Editor SQL no Supabase)
-- Create a messages table
create table messages (
id uuid default gen_random_uuid() primary key,
content text not null,
user_id uuid references auth.users,
created_at timestamptz default now()
);
-- Enable Row Level Security
alter table messages enable row level security;
-- Policy: anyone can read messages
create policy "Messages are viewable by everyone"
on messages for select using (true);
-- Policy: authenticated users can insert their own messages
create policy "Users can insert their own messages"
on messages for insert
with check (auth.uid() = user_id);
Assinaturas em tempo real
// components/Chat.jsx
'use client';
import { useState, useEffect } from 'react';
import { supabase } from '@/lib/supabase';
export default function Chat() {
const [messages, setMessages] = useState([]);
useEffect(() => {
// Load existing messages
supabase.from('messages').select('*').order('created_at')
.then(({ data }) => setMessages(data || []));
// Subscribe to new messages in real time
const channel = supabase
.channel('messages')
.on('postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'messages' },
(payload) => {
setMessages(prev => [...prev, payload.new]);
}
)
.subscribe();
// Cleanup subscription
return () => { supabase.removeChannel(channel); };
}, []);
const sendMessage = async (content) => {
const { data: { user } } = await supabase.auth.getUser();
await supabase.from('messages').insert({ content, user_id: user.id });
};
return (
<div>
{messages.map(m => <div key={m.id}>{m.content}</div>)}
</div>
);
}
Autenticação
// Sign up
async function signUp(email, password) {
const { data, error } = await supabase.auth.signUp({ email, password });
if (error) throw error;
return data;
}
// Sign in
async function signIn(email, password) {
const { data, error } = await supabase.auth.signInWithPassword({ email, password });
if (error) throw error;
return data;
}
// OAuth (Google, GitHub, etc.)
async function signInWithGitHub() {
await supabase.auth.signInWithOAuth({ provider: 'github' });
}
// Get current user
const { data: { user } } = await supabase.auth.getUser();
// Sign out
await supabase.auth.signOut();
Componentes do servidor e busca de dados
// app/page.jsx - Server Component fetching data
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';
export default async function Page() {
const cookieStore = cookies();
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
{ cookies: { get: (name) => cookieStore.get(name)?.value } }
);
const { data: messages } = await supabase
.from('messages')
.select('*')
.order('created_at', { ascending: false })
.limit(20);
return <MessageList initialMessages={messages} />;
}
Segurança em nível de linha: a chave para dados seguros
Supabase usa PostgreSQL Row Level Security (RLS) para controlar o acesso aos dados. Como o cliente se conecta diretamente à chave anônima, as políticas RLS são o que mantém os dados seguros – elas definem quem pode ler/escrever o quê. Sempre habilite o RLS em suas tabelas e escreva políticas. Sem RLS, seus dados ficam expostos. O RLS não é opcional para produção — é a base de segurança do modelo de cliente direto.
Implantação
# Deploy to Vercel (seamless with Next.js)
# 1. Push to GitHub
# 2. Import the repo in Vercel
# 3. Add environment variables (NEXT_PUBLIC_SUPABASE_URL, ANON_KEY)
# 4. Deploy
# Supabase is already hosted - no backend deployment needed.
# Your Next.js frontend on Vercel + Supabase backend = full-stack app live.
Perguntas Frequentes
P: Supabase é uma boa alternativa para construir meu próprio backend?
R: Sim, para muitos aplicativos — ele fornece um banco de dados PostgreSQL real, autenticação, armazenamento e tempo real sem construir infraestrutura de back-end. Você obtém SQL padrão (não um banco de dados proprietário), então não fica preso. É excelente para desenvolvimento rápido de pilha completa e MVPs.
P: Como funciona o tempo real no Supabase?
R: Supabase escuta as alterações do PostgreSQL e as envia para clientes inscritos por meio de WebSockets. Você assina eventos INSERT/UPDATE/DELETE em uma tabela e seu retorno de chamada é acionado quando os dados são alterados. O código mínimo oferece atualizações ao vivo – ótimo para bate-papo, notificações e recursos colaborativos.
P: É seguro usar o Supabase diretamente do cliente?
R: Sim, SE você usar a segurança em nível de linha (RLS). Como o cliente se conecta à chave anônima, as políticas de RLS controlam o que cada usuário pode ler/gravar. Sempre habilite o RLS e escreva políticas — é a base da segurança. Sem RLS, seus dados ficam expostos. Nunca pule isso na produção.
P: Supabase ou Firebase?
R: Supabase usa PostgreSQL (SQL padrão, relacional, sem lock-in) e é de código aberto/auto-hospedável. O Firebase usa um banco de dados NoSQL proprietário. Escolha Supabase se preferir SQL, dados relacionais e evitar aprisionamento; Firebase por seu ecossistema maduro e se o NoSQL se ajusta aos seus dados. Ambos oferecem autenticação e tempo real.
P: Posso auto-hospedar o Supabase?
R: Sim — Supabase é de código aberto e pode ser auto-hospedado, evitando a dependência de um fornecedor. A maioria começa com a nuvem gerenciada (nível gratuito generoso) e pode se auto-hospedar posteriormente, se necessário. A opção de auto-hospedagem é uma vantagem importante em relação às alternativas fechadas.
Conclusão
Next.js + Supabase é uma maneira poderosa e rápida de construir aplicativos full-stack em tempo real em 2026. Supabase fornece umbanco de dados PostgreSQL real, autenticação integrada e assinaturas em tempo real – emparelhando perfeitamente com Next.js. O fluxo de trabalho: criar tabelas com SQL, habilitar a segurança em nível de linha com políticas (crítica para acesso seguro direto do cliente), assinar alterações em tempo real e usar autenticação Supabase para usuários. Implante o front-end Next.js no Vercel e, como o Supabase já está hospedado, você terá um aplicativo full-stack ativo, sem infraestrutura de back-end para gerenciar. A principal regra de segurança é sempre ativar o RLS — é o que mantém seguros os dados acessados diretamente. Para bate-papo, ferramentas colaborativas, painéis e MVPs, essa pilha permite que você crie aplicativos full-stack em tempo real de maneira extremamente rápida, sem criar ou gerenciar um back-end.
🔗 Share this article
✍️ Leave a Comment