Drive (ride-hailing)
Corridas para passageiro e motorista com mapa Mapbox. Estimativa de preço no servidor, pagamento real via Stripe no futuro.
Drive é o módulo de ride-hailing do kit: o usuário pede uma corrida como passageiro ou entra no modo motorista para aceitar solicitações por perto. O fluxo completo roda nos 3 backends (Firebase, Supabase, API REST) com a mesma UI.
| Papel | O que faz |
|---|---|
| Passageiro | Escolhe embarque e destino no mapa, vê distância, duração e valor estimado, acompanha a corrida em tempo real |
| Motorista | Cadastra o veículo, fica online, aceita corridas próximas e conduz até concluir ou cancelar |
O mapa usa Mapbox via flutter_map (tiles HTTP, funciona em nativo e web). A rota e o preço são calculados no servidor (Mapbox Directions + coeficientes que você define), não no app.
Os mapas iniciais do motorista e do passageiro usam zoom 16, inclusive ao receber a localização inicial e ao recentralizar. Os tiles Mapbox mantêm dimensão lógica de 512, com retina nativa para preservar a legibilidade dos nomes das ruas. Quando há uma rota, o mapa ajusta o enquadramento automaticamente para mostrar o trajeto completo.
O valor mostrado na tela é apenas uma estimativa. O kit não cobra o passageiro nem repassa pagamento ao motorista. Para cobrança real, integre o módulo Stripe (web) ou outro provedor no seu backend.
Implementação
Pelo MCP: peça ao assistente "adiciona drive no meu projeto". Ele roda add_feature por você. Veja MCP do Kasy.
-
Ative o módulo (não vem no modo Rápido por padrão):
kasy add drive # adiciona (pede token Mapbox e coeficientes de preço) kasy remove drive # remove kasy add --list # mostra o que está ligadoO
kasy add drivegravaMAPBOX_ACCESS_TOKENno.env, semeia os coeficientesDRIVE_*e, no Firebase/Supabase, tenta gravar o token Mapbox como secret do servidor. -
Crie o token Mapbox:
- Crie conta em mapbox.com
- Gere um access token público (
pk.…) - Configure limites de uso e restrições de URL/bundle no console Mapbox
-
Configure secrets e coeficientes:
kasy configure driveOu pela seção Drive (Ride-hailing) do
kasy configure:Variável Onde fica Uso MAPBOX_ACCESS_TOKEN.envdo appTiles e mapa no Flutter MAPBOX_ACCESS_TOKENSecret do servidor (Firebase/Supabase) Directions e cálculo de preço no backend DRIVE_BASE_FAREfunctions/.envou Supabase secretsTarifa base (padrão 5)DRIVE_PRICE_PER_KMidem Preço por km (padrão 1.5)DRIVE_PRICE_PER_MINidem Preço por minuto (padrão 0.25)DRIVE_CURRENCYidem Código ISO da moeda (padrão USD)No API REST, os coeficientes ficam no
.envdo seu servidor. Veja o contrato emdocs/drive.md(entregue no projeto) e o README do patch API.Pelo MCP: cole o token Mapbox e os coeficientes no chat e peça "configura o Drive". O assistente grava com
configure_project_keys(Firebase/Supabase). Veja MCP do Kasy. -
Faça o deploy do backend:
Backend O que fazer Firebase kasy deploy(publicadriveFunctions+ triggers de push)Supabase supabase db push(migrationdrive) +supabase functions deploy request-rideAPI REST Implemente os endpoints POST /drive/rides,POST /drive/rides/{id}/acceptetc. (veja README do patch)Pelo MCP (Firebase): "faz o deploy do backend" (
deploy_backend). -
Confirme as permissões nativas. O app pede localização em runtime (embarque, motorista online). No iOS,
Info.plistjá traz as chaves de uso quando o módulo está ligado. Valide em dispositivo real antes de publicar. -
Teste o fluxo. Duas formas:
-
Sozinho, sem GPS de verdade: fora de produção, ligue "Teste automatizado" no menu lateral do Drive, ele simula o motorista andando uma rota fixa, então uma única conta testa passageiro e motorista alternando de papel. Veja Modo de teste automatizado abaixo.
-
Com dois dispositivos ou contas (ou emulador + físico), simulando passageiro e motorista ao mesmo tempo:
- Abra Configurações
- Toque no tile Drive (ícone de carro)
- Escolha Pedir corrida (passageiro) ou Modo motorista
-
-
Para cobrança real (fora do escopo do módulo Drive), adicione Stripe (web) ou outro gateway e amarre a cobrança ao evento
completeda corrida no seu backend.
Informações
Como o fluxo funciona
Na primeira abertura (Configurações → Drive), o app pergunta uma vez se o usuário quer usar como passageiro ou motorista e salva a escolha. Depois disso, o Drive abre direto na tela do papel salvo; a troca é pelo menu lateral do próprio Drive.
A corrida ativa é reconhecida em qualquer navegador ou dispositivo logado na mesma conta, trocar de aparelho no meio de uma corrida não perde o acompanhamento nem deixa pedir uma corrida duplicada por engano.
Passageiro:
- Busca o destino por texto ou ajusta os pinos de embarque/destino no mapa
- Vê a rota, distância, tempo e o preço estimado (calculado no servidor)
- Pede a corrida e acompanha em tempo real: posição do motorista, veículo e placa, ETA ao vivo
- Se nenhum motorista aceitar em cerca de 1 minuto, aparece "Nenhum motorista disponível" com contagem regressiva e a opção de tentar novamente, até 2 vezes. Depois disso só resta cancelar e tentar mais tarde
- Pode cancelar apenas enquanto a corrida está
requestedouaccepted. Depois que embarcou (in_progress), não dá mais para cancelar pelo app
Motorista:
- Precisa cadastrar o veículo (onboarding) antes de ficar online. O switch abre o cadastro automaticamente se faltar
- Online liga o GPS contínuo: a posição é publicada no backend e é ela que o passageiro vê no mapa
- Corridas próximas chegam como um overlay em tela cheia com som e vibração, com Aceitar e Recusar (recusar só esconde para aquele motorista). Enquanto está numa corrida, não recebe novas solicitações
- Ao aceitar, entra na navegação até o embarque. O botão "Embarquei o passageiro" só libera quando o GPS está a até 100 m do ponto de embarque
- Depois disso navega até o destino, e "Concluir corrida" só libera a até 100 m do destino. Fora do raio, o botão fica desabilitado com uma dica na tela
Regras de transição (validadas no servidor)
O botão liberar na tela não é a única proteção. O backend valida cada transição nos 3 backends, com as mesmas regras:
| Ação | Só é aceita quando |
|---|---|
| Aceitar | Corrida ainda requested (se dois motoristas aceitam, só o primeiro ganha) |
| Iniciar (embarquei) | Corrida accepted e o chamador é o motorista designado |
| Concluir | Corrida in_progress e o chamador é o motorista designado |
| Cancelar | Corrida ainda não completed nem canceled; só passageiro ou motorista da corrida |
Localização em segundo plano
Por padrão, o GPS do motorista só é publicado com o app aberto (primeiro plano). Se ele minimizar no meio de uma corrida, a posição para de atualizar até ele voltar pro app.
Pra manter a posição chegando mesmo com o app minimizado, adicione o módulo Localização em segundo plano (kasy add background_location). Ele se conecta sozinho ao Drive: liga automaticamente pro motorista enquanto ele está online, sem precisar editar nada.
Hoje esse rastreamento em background é só do lado do motorista. O passageiro não é acompanhado em background porque nenhuma tela ou dado do Drive depende disso: a posição dele é capturada uma única vez, no momento do pedido (o pickup fixo que o motorista vê no mapa), e não muda depois disso mesmo com o app aberto.
Modo de teste automatizado (dev)
Fora de produção (qualquer build com ENV diferente de prod), o menu lateral do Drive tem um item "Teste automatizado". Ligado, ele deixa testar o fluxo inteiro, pedir, aceitar, recusar, embarcar, concluir, sozinho, com uma única conta, sem precisar de dois dispositivos nem de GPS de verdade:
- A localização vira uma rota fixa simulada (um trecho real, roteirizado pelo Mapbox); o motorista "anda" essa rota sozinho, num ritmo acelerado (a corrida inteira leva segundos, não minutos).
- Nas telas de corrida em andamento, um botão próprio na barra superior (ícone de carro/pino) troca sua própria conta para o outro papel, vira motorista pra você mesmo aceitar/recusar aquela solicitação, ou volta a ser passageiro, já que é a mesma pessoa testando os dois lados. O botão de voltar continua se comportando como em produção (cancela a corrida ou sai da navegação), sem misturar as duas ações.
- Recusar não cancela a corrida: ela continua
requestede visível para outros motoristas, igual em produção.
Só nesse modo: um hot restart (R maiúsculo no flutter run/kasy run, ou recarregar a aba do zero) reinicia a posição do veículo simulado, ele volta a andar a rota do começo, mesmo que já tivesse chegado. Isso é uma limitação do simulador (a posição só existe na memória do app, nunca é salva em lugar nenhum), não um bug do fluxo real. Em produção não existe equivalente: o GPS do celular é uma fonte externa que continua de onde estava, nenhum restart "esquece" a posição do motorista.
Esse toggle nunca aparece em build de produção (ENV=prod), nenhum usuário final o vê.
Onde ver no Firebase Console
O Drive não grava motorista nem corrida na aba Authentication. Lá só existe a conta e o User UID. Os dados ficam no Firestore do mesmo projeto que o app usa.
| O que procurar | Onde | Nota |
|---|---|---|
| Conta de teste | Authentication → Users | Copie o User UID |
| Cadastro de motorista | Firestore → drivers/{uid} | Mesmo {uid} da Authentication |
| Corridas | Firestore → rides/ | Criadas pela callable requestRide |
| Push do aparelho | Firestore → users/{uid}/devices/ | Não é nome do motorista |
Teste automatizado: só o GPS é simulado. Pedir, aceitar e mudar status sempre vão pro backend. Se rides/ estiver vazio, confira deploy das functions, secret Mapbox e se drive_api.dart usa a mesma região do functionsRegion no kit_setup.json.
No Supabase, use o schema drive (drivers, rides) no Table Editor.
Testar sem o setup completo
Com withDrive ligado, as telas do Drive abrem mesmo sem token Mapbox (o mapa fica vazio). Para o fluxo ponta a ponta (solicitar, aceitar, iniciar, concluir), você precisa do token no .env, dos secrets configurados e do backend deployado.
| Situação | O que funciona |
|---|---|
| Debug sem token Mapbox | Telas abrem; mapa sem tiles |
| Debug com token + backend local/deploy | Fluxo completo passageiro + motorista |
| Release sem token | Mapa quebrado; não publique assim |
O que vem na UI
- Entrada: intro do Drive com escolha de papel na primeira vez (Configurações → Drive); papel fica salvo
- Passageiro: home com mapa em tela cheia, busca de destino, ajuste de pinos, estimativa e acompanhamento ao vivo
- Motorista: onboarding do veículo, switch online/offline, overlay de corridas próximas, navegação com rota progressiva e ETA
- Push: notificações quando uma corrida é criada ou muda de status (Firebase triggers / Supabase equivalente)
Não há sistema de papéis separado: quem tem perfil em drivers/{uid} é motorista; qualquer usuário logado pode pedir corrida.
Atualizado em 03/11/2026

