EduDev Projetos Palavra Falada
Mobile App · React Native · Projeto de extensão

Palavra Falada

Aprender a ler começa por ouvir — app de prática de leitura em voz alta, sem fricção nenhuma pro aluno.

Professor monta a turma e a lista de palavras. Aluno escaneia um QR Code, sem criar conta nem lembrar senha, e já começa a praticar: ouve a palavra falada pelo celular e repete em voz alta. Projeto de extensão universitária em grupo, com backend real em Supabase e app publicado como APK de testes.

React Native Expo Router Supabase PostgreSQL + RLS EAS Build

Telas do app

Fluxo pensado pro aluno nunca travar em nada técnico — só a palavra e o botão de ouvir.

Palavra Falada
Sou aluno
Sou professor
QR Code da Turma
7X9K2A
Código curto da turma — dá pra projetar em tela cheia na lousa
Tarefas
BOLA
CASA
GATO
PATO
← Tarefa ←
CASA
Toque em ✓ depois de repetir a palavra em voz alta
Parabéns!
Você concluiu a tarefa com sucesso!

Ler em voz alta,
sem fricção nenhuma.

O Palavra Falada nasceu na disciplina de extensão (Ciência da Computação) em grupo, com um objetivo simples de enunciar e difícil de executar bem: deixar um aluno praticar leitura em voz alta sem precisar de conta, senha ou qualquer fricção técnica no meio do caminho.

O professor cria a turma e a lista de palavras pelo celular ou navegador. O aluno só escaneia um QR Code — ou digita um código curto de 6 caracteres — e cai direto na prática: ouve a palavra (texto-pra-voz em português do Brasil) e repete em voz alta. Fui responsável pela maior parte da implementação de frontend/backend e por resolver os bugs de produção que só aparecem depois que o app sai do ambiente de desenvolvimento.

Tipo App Mobile + Backend
Stack React Native + Expo + Supabase
Plataforma Android · Web
Status APK de testes publicado
"A parte mais difícil nunca foi o React Native — foi descobrir por que o Postgres deixava passar uma RLS certa e ainda assim bloqueava tudo. O detalhe que ninguém vê é sempre o que mais ensina."
E
Eduardo Martins Desenvolvedor

Tudo o que ele faz

Construído pra quem está alfabetizando, não pra quem entende de app.

Entrada sem conta

Aluno escaneia o QR Code da turma (ou digita o código curto) e já começa a praticar — zero cadastro, zero senha pra esquecer.

Voz em português do Brasil

Cada palavra é falada pelo motor de texto-pra-voz do próprio aparelho — sem depender de áudio pré-gravado.

Professor no controle

Cria, edita e exclui turmas e tarefas; acompanha quem já entrou em cada turma e consegue ouvir qualquer palavra antes de aplicar.

Menu lateral único

Um cabeçalho e um menu reaproveitados em todas as telas do professor — unificado depois de várias telas terem crescido de forma inconsistente.

Código curto da turma

Trocamos o UUID gigante do QR Code por um código de 6 caracteres — mais fácil de ler, digitar e projetar na lousa.

Tela limpa pro aluno

Só a palavra, o ícone de ouvir e o botão de confirmar. Nada de categoria, prefixo técnico ou menu sobrando na tela.

Confirmação guiada

O aluno ouve, repete em voz alta e confirma tocando no ✓ — prática acompanhada pelo professor, sem fingir que existe reconhecimento de voz automático.

APK de testes direto no ar

Build gerado via EAS e publicado como Release no GitHub — instala direto no Android, fora da Google Play, pra quem quiser testar agora.

Tecnologias utilizadas

App multiplataforma com backend real, não só telas bonitas.

React Native + Expo

Base do app, rodando em Android e Web a partir do mesmo código.

Expo Router

Navegação por arquivos, com grupos de rotas separando o fluxo do aluno e do professor.

Supabase

Auth, banco Postgres e API de dados — backend completo sem servidor próprio pra manter.

PostgreSQL + RLS

Row Level Security controlando o que aluno (anônimo) e professor (autenticado) podem ler e escrever.

Câmera + leitura de QR

Scanner nativo lê o código da turma e resolve pro id real via consulta ao banco.

Text-to-Speech nativo

Fala cada palavra em português do Brasil usando a engine de voz do próprio aparelho.

EAS Build

Pipeline de build na nuvem gerando o APK direto a partir do código, sem Android Studio local.

Context API

Modal de alerta/confirmação próprio via Context — substitui o Alert nativo, que não funciona na versão web.

Desafios técnicos

Os bugs que só aparecem fora do ambiente de desenvolvimento — e como rastreei cada um até a causa real.

01

RLS certa, acesso bloqueado do mesmo jeito

Criei as policies de Row Level Security corretas e mesmo assim o app continuava sem achar nenhuma turma. A causa não estava nas policies: faltava o GRANT de acesso à API de dados pro papel anon — uma camada de permissão que é avaliada antes da RLS, e que falha em silêncio (sem erro, só devolve vazio).

02

Alert.alert que não existe na Web

Todo Alert.alert do app — inclusive a confirmação de exclusão — simplesmente não fazia nada ao rodar na versão Web. O motivo: no react-native-web, o módulo de Alert é um stub vazio. Resolvi com um sistema próprio de modal via Context API, funcionando igual em qualquer plataforma.

03

App fechando sozinho no build de produção

O APK gerado pelo EAS abria e fechava na hora, sem nenhum erro visível. Capturando o log de crash via adb logcat, achei a causa: o .env está no .gitignore, e o EAS Build respeita isso — as variáveis do Supabase nunca chegavam no build. Corrigido cadastrando as variáveis direto como EAS Environment Variables, fora do arquivo local.

04

Cabeçalho duplicado em quase toda tela

O Stack Navigator do grupo do professor estava configurado com cabeçalho nativo ligado por padrão, em cima de cabeçalhos já customizados em cada tela — resultado: duas barras de título empilhadas. Padronizei num único componente de cabeçalho reusável e desliguei o nativo onde já existia um customizado.

05

QR Code ilegível com UUID

O código da turma começou como um UUID inteiro — ótimo pra chave de banco, péssimo pra alguém digitar manualmente ou ler no campo de teste. Troquei por um código curto de 6 caracteres gerado na criação da turma, resolvido pro id real via consulta no momento da leitura.

06

Clique "vazando" pro card inteiro

O botão de excluir turma ficava dentro do card inteiro (que também navega ao tocar). No nativo isso nunca foi problema, mas no React Native Web o clique sobe pelo DOM — excluir também disparava a navegação. Separei a área clicável de navegação dos botões de ação, que passaram a ser elementos irmãos, não aninhados.

O que eu aprendi

Cada projeto deixa marcas. Aqui ficam as mais importantes deste.

Backend

RLS não é a permissão inteira

Policies corretas não bastam se o GRANT de base da API não existir — são duas camadas distintas, e a falha em uma delas não gera erro nenhum.

Debugging

Depurar sem tela de erro

Build de produção não mostra overlay de erro — aprendi a capturar crash via logcat e decodificar logs comprimidos em brotli direto da API do EAS.

Multiplataforma

Web não é só "React Native de brinde"

APIs nativas como Alert e comportamento de clique em elementos aninhados mudam de verdade entre nativo e react-native-web — testar só num ambiente esconde bugs reais.

DevOps

Build na nuvem tem regras próprias

O EAS Build ignora o que o .gitignore ignora — variáveis de ambiente locais precisam virar configuração explícita do projeto, não só um arquivo .env no disco.

UX

Simplicidade é decisão, não falta de feature

Tirar categoria, prefixo e menu da tela do aluno foi tão importante quanto qualquer funcionalidade nova — menos escolha é o produto certo pra esse público.

Trabalho em equipe

Decisão de produto também é código

Boa parte das mudanças vieram de feedback direto do time e do orientador — traduzir "tá poluído" ou "não funciona" em causa raiz técnica é parte do trabalho.

Gostou do projeto?

O Palavra Falada é um trabalho em grupo, mas boa parte da implementação e dos bugs de produção resolvidos aqui foram meus. Veja o código ou conheça outros projetos do portfólio.