Pular para o conteúdo
Todos os case studies

Case study · Logística

Rastreamento de entregas em tempo real

Um app crítico para entregadores, com atualizações de entrega em tempo real via Firestore, Coroutines e Flow, e testabilidade com Koin.

Cargo
Engenheiro Android
Empresa
T10
Período
ago 2022 – fev 2023

Contexto

A T10 atua em logística. De agosto de 2022 a fevereiro de 2023, desenvolvi e mantive o app dos entregadores, uma ferramenta crítica: quando ele para, as entregas param junto. O app é feito com Kotlin, MVVM e Firebase Firestore.

Desafio

  • Tempo real, o tempo todo. Os dados das entregas mudam o tempo inteiro, e o entregador precisa ver cada atualização assim que ela acontece.
  • Sem vazamentos nem telas travadas. Os listeners do Firestore precisam começar e parar junto com a tela, e as atualizações têm que chegar à UI sem bloquear a main thread.
  • Confiança para mudar. Um app crítico precisa de código testável de forma isolada, o que exige dependências que possam ser trocadas.

Abordagem

Fluxos reativos com Coroutines e Flow. Encapsulei os snapshot listeners do Firestore em callbackFlow, transformando callbacks em flows frios. O listener é registrado quando a UI começa a coletar e removido no awaitClose quando ela para, então não existe listener esquecido.

DeliveryRepository.kt
fun observeDelivery(id: String): Flow<Delivery> = callbackFlow {
    val registration = firestore
        .collection("deliveries")
        .document(id)
        .addSnapshotListener { snapshot, error ->
            if (error != null) {
                close(error)
                return@addSnapshotListener
            }
            snapshot?.toObject<Delivery>()?.let { trySend(it) }
        }

    awaitClose { registration.remove() }
}

Estado que sobrevive à rotação. Os repositórios expõem flows, e os ViewModels os transformam em StateFlow com stateIn. A UI sempre mostra o último estado conhecido, e uma mudança de configuração não reinicia o fluxo.

Injeção de dependência com Koin. Integrei o Koin para declarar as dependências em módulos. Trocar as implementações baseadas no Firestore por fakes nos testes ficou simples, e a arquitetura modular ficou mais estável.

Arquitetura

Firestoredocumentos de entregacallbackFlowsnapshot listenerRepositoryFlow<Delivery>ViewModelStateFlowUIstatus ao vivoinjetainjetaGrafo de dependências com Kointrocado por fakes nos testes
Simplificado. O listener só existe enquanto a UI está coletando, então nada vaza.

Resultados

  • Rastreamento de entregas em tempo real com fluxos reativos usando Coroutines, Flow e Firestore.
  • Listeners atrelados ao ciclo de vida da UI, então as atualizações param assim que ninguém está olhando.
  • Mais testabilidade e uma arquitetura modular mais estável com Koin.

Stack

As ferramentas por trás desse trabalho, todas usadas em produção:

  • Kotlin
  • MVVM
  • Firebase Firestore
  • Coroutines
  • Flow
  • Koin

Os detalhes foram simplificados e os nomes de clientes omitidos para respeitar a confidencialidade.

Próximo case study

Pagamentos Pix na escala de um superapp

Zup Innovation

Quer construir algo assim?

Estou aberto a vagas de Android sênior em empresas internacionais.