Motocicletas e tecnologia, unidas com Supabase

Motocicletas e tecnologia, unidas com Supabase

A maioria dos desenvolvedores pensou em criar uma ferramenta para usá-la em algo pelo qual somos apaixonados. Alguns de nós fizeram isso acontecer.

Ao longo dos meus 12 anos como profissional, iniciei pelo menos 12 candidaturas desta natureza. No início de cada um, há um hype muito intenso, mas vai diminuindo gradativamente até que o projeto seja abandonado. Soa familiar? Neste artigo, vou contar como finalmente atingi esse objetivo com um aplicativo feito do zero, vinculado ao que eu gosto e até com lucro: NorthBikers.

Durante os últimos 3 anos, -quase- todos os fins de semana tenho visitado diferentes grupos de motociclistas para visitar lugares muito remotos, com estradas de terra, como são comumente conhecidos. Há um ano sou o capitão da rota. Em poucas palavras: sou eu quem planeja, convoca, dirige e cuido do grupo ao longo da jornada.

E adivinha? Como tantas vezes no passado, pensei em melhorar minha experiência nesta atividade pela qual sou apaixonado por meio de um aplicativo

NorthBikers: Fase 1

No início, a necessidade era muito básica: ter postos de controle onde faríamos paradas para nos reagrupar e que também funcionassem como pontos onde os colegas que estavam atrasados ​​pudessem nos alcançar.

Eu me considero um especialista em Angular, então um web app bem simples baseado neste framework foi suficiente: uma lista de registros, onde cada um consistia no nome, latitude e longitude do local.

Além deste frontend, eu precisava de um local para salvar e consultar as informações. Nesse ponto, como o aplicativo era bem simples, decidi explorar um backend as a service, pois exigia apenas um banco de dados e uma API para consultá-lo, mas também queria poder estendê-lo facilmente no futuro, se necessário .

Tenho muita experiência com Firebase. No entanto, decidi explorar (e aprender) uma nova tecnologia/plataforma: Supabase. Essa ferramenta possui serviços semelhantes ao Firebase, embora a principal diferença seja que possui um banco de dados relacional (PostgreSQL) em vez de um baseado em documentos.

Vale ressaltar que o Supabase fornece uma interface que permite manipular os dados de forma simples. Então decidi temporariamente inserir os registros manualmente, em vez de implementar funcionalidades extras no aplicativo ou em um back office.

Neste ponto, a arquitetura é extremamente simples:

Plain & Simple: um frontend conectado a um banco de dados por meio das APIs que o Supabase fornece por padrão. Mais tarde, você verá que essa arquitetura permaneceu quase intacta.

Isso funcionou muito bem para nós, porque serviu ao propósito de nos dar uma ideia clara dos locais de reagrupamento.

Eu não sou um grande fã de adicionar componentes sociais a aplicativos apenas por isso. Um componente social deve servir a um propósito. Neste caso, devido ao tipo de percursos que fazemos, é de GRANDE ajuda saber quem vai e certificar-se de que cada um dos participantes chegou aos checkpoints. Se alguém não fez isso, provavelmente se perdeu, aconteceu alguma coisa com sua moto ou com ele, nesse caso, você tem que voltar para ajudá-lo.

Um componente social nem sempre é como eles o pintam. Não será necessariamente uma linha do tempo cheia de fotos, vídeos e status de outras pessoas. Para um servidor, ele deve fornecer uma maneira significativa de interagir com os usuários. No nosso caso, simplesmente ver alguém fazer check-in em um checkpoint era mais do que suficiente (na época).

A implementação foi simples:

  • Habilitar o componente de autenticação (Login, Registro, Perfil).
  • Adicionar novas tabelas no banco de dados para salvar detalhes de usuários e check-ins nos pontos de verificação.
  • No frontend, permitir que os usuários insiram um ponto de verificação e façam check-in.

A arquitetura permaneceu a mesma, com a diferença de que além de utilizar apenas o módulo de banco de dados Supabase, o módulo de autenticação passou a ser utilizado.

Acabei com o que posso chamar de produto principal, que cumpre uma tarefa específica (ou algumas tarefas) e que pelo menos meu grupo e outros conhecidos queriam e poderiam usar.

Chaves para terminar bem

Aqui quero dizer qual foi a chave para chegar a isso: mantive 👏🏽 as 👏🏽 coisas 👏🏽 simples 👏🏽.

Usei tecnologias que conhecia ou eram muito fáceis de usar, usei serviços gratuitos e adicionei apenas a funcionalidade que eu precisava. Apesar de ter experiência com serviços como AWS, Azure e ter construído backends do zero com NodeJS, C# e PHP, peguei e evitei tentar reinventar a roda usando o Supabase.

Curiosidade: por fim, a Supabase hospeda seus bancos de dados na AWS.

Outro detalhe que ajudou foi conter a vontade de usar React no frontend. Eu sei que este comentário levantou mais de uma sobrancelha, mas o motivo não é o que você pensa: eu costumava lidar com o React em um nível muito básico e tenho certeza que implementá-lo aqui teria me ajudado a conhecê-lo muito melhor. No entanto, também tenho certeza de que teria consumido mais tempo, talvez me levando a abandonar o projeto, como na maioria dos casos.

Isso me permitiu construir tudo sem ser bloqueado por problemas técnicos e também me permitiu não ser pressionado por custos mensais de servidores ou serviços.

NorthBikers: Fase 2

O que foi construído na Fase 1 era funcional e até certo ponto suficiente. No entanto, eu queria levá-lo para o próximo nível.

Como mencionei no início, o NorthBikers era, em sua primeira fase, um aplicativo web Angular, acessado é claro pelo navegador.

Aqui resolvi analisar meu público. Mesmo sendo um grupo com faixa etária entre 22 e 60 anos (ou mais), todos usavam o celular. Afinal, quem leva seu laptop em um passeio de moto? Bem, às vezes eu...

Então decidi melhorar a experiência do usuário e, pelo menos do ponto de vista de UX, tornar o aplicativo mais conveniente para todos. Como o desenvolvimento foi feito em Angular e, felizmente, estou com preguiça de atualizar e desenvolver aplicativos nativos para iOS e Android, optei por usar o Ionic. Simplificando, o Ionic é Angular com estilos projetados para dispositivos móveis, integrando-se muito facilmente com bibliotecas/frameworks como Cordova e Capacitor para acessar chips nativos.

Com isso em mente:

  • Migrei meu código de Angular para Ionic (reutilizei quase 100% da lógica)
  • Permiti que o usuário fizesse upload de uma foto no check-in. Isso é opcional, embora amplamente utilizado hoje.
  • Além de continuar publicando o aplicativo na web, empacotei o código para iOS e Android usando Capacitor e publiquei em suas respectivas lojas.

Considerando a popularidade da opção de upload de fotos junto com o check-in, foi um tanto natural implementar um feed onde as fotos enviadas por outros usuários são exibidas. Isso foi experimental, mas gostei muito: no mundo do motociclismo, gostamos muito de compartilhar nossas experiências. Recursos como curtir, comentar e reportar fotos também foram implementados.

Aqui a arquitetura muda um pouco e, do lado do Supabase, além de autenticação e banco de dados, adicionamos o uso de seu serviço de armazenamento.

Nesta fase, surgiu uma novidade que parece mínima (principalmente no frontend): o cálculo da distância entre um ponto e outro.

Olho aqui. Ninguém ia me dizer: “Ei Eduardo, seria ótimo se você usasse a API da matriz de distância para calcular a distância entre pontos” 😅. Acabei de me deparar com a mesma pergunta muitas vezes: Qual é a distância para chegar a X? Qual é a distância entre Y e Z? O acima às vezes por curiosidade, ansiedade ou para saber se o combustível seria suficiente para chegar lá.

Então, decidi implementar esse recurso. Ao adicionar/modificar os pontos de verificação, faço chamadas para a API Google Distance Matrix para calcular a distância entre os pontos. Isso melhorou muito a experiência, além de ajudar a dar certeza e segurança no trajeto.

Portanto, adicionamos um novo elemento ao backend na arquitetura:

Chaves para terminar bem

Eu já tinha o núcleo funcionando corretamente. Neste ponto, tive que decidir entre duas alternativas:

1- Deixar o aplicativo como estava, ou seja, funcionando bem, mas até certo ponto estagnado.

2- Estendendo-o e correndo o risco de fazer errado, demorar muito ou simplesmente entregar algo que ninguém usaria e atrapalhar as funcionalidades centrais.

Várias vezes ouvi (e disse) a frase “Se ele funcionar, não mexa”. Mas descobri que uma maneira de movê-lo e não apenas continuar puxando, mas puxando melhor é analisando as necessidades do seu público.

Você tem que ter cuidado, no entanto. Quando você pergunta a um usuário o que ele quer, dificilmente obterá uma resposta real sobre o que ele realmente precisa. Em vez disso, analise e use seu conhecimento para obter os melhores resultados.

Outro ponto extremamente importante é que você deve ser muito esperto ao escolher os recursos que vai implementar, pois algo tão simples como um rótulo de texto que mostre a distância entre dois pontos pode ser mais útil do que tentar fazer uma cópia do TikTok ou Facebook.

Para tudo isso, quando comecei a ganhar dinheiro com meu aplicativo? Já quase chegamos. Isso acontece na fase 3:

NorthBikers: Fase 3

Em setembro de 2021, participei do Rally ADV NL. Esses tipos de competições geralmente têm uma pista (ou rota) definida que você deve concluir. O lugar que você vai conseguir na competição dependerá do tempo que você leva para chegar à linha de chegada.

O rally em que participei foi diferente. Havia um conjunto de locais para visitar, distribuídos por todo o estado e cada um com uma determinada pontuação (quanto mais distante ou mais difícil o local, maior a pontuação). Este rally é mais sobre estratégia, aventura e turismo do que velocidade.

A forma de verificar se você visitou algum dos pontos era tirar uma foto sua e, ao final de sua participação, fazer upload de todas as fotos para um Google Drive. Terminado o período em que você poderia enviar suas provas, uma equipe de 15 pessoas localizadas no local do evento analisou todas as fotos enviadas para o Google Drive e atribuiu uma pontuação a cada uma.

Meu amigo Joaquín Lam (o organizador do evento) me disse que esse processo de qualificação levou a equipe cerca de 6 horas de trabalho muito intenso.

Você consegue adivinhar para onde estou indo com o que estou lhe dizendo? Muito provavelmente você pensou o mesmo que eu: é algo que pode ser automatizado e agilizar todo o processo de qualificação.

O primeiro passo para colocar o aplicativo para realizar essa automação foi complementá-lo com um painel onde Joaquín pudesse acessar e gerenciar seu evento.

Como o tempo era relativamente curto para implementá-lo e ainda tinha problemas de evolução e correção de bugs pendentes no aplicativo, pedi ajuda a um colega (Miguel) para construir o dashboard. Miguel é especialista em React, por isso usamos para fazer esse desenvolvimento. A arquitetura ficou assim:

Vamos começar com as partes mais óbvias para implementar nesta terceira fase:

  • Na aplicação móvel, a acumulação de pontos ao nível do evento, através de check-ins.
  • Captura de geolocalização no check-in.
  • Captura de fotos no check-in
  • O site de administração, com autenticação simples, e uma lista de participantes, atualizada em tempo real com as pontuações dos participantes.
  • O mais importante: uma seção de detalhes por participante, onde o administrador pode ver todos os check-ins de cada participante, ter informações de geolocalização, foto e distância entre o local de check-in e o próprio checkpoint.

Fazendo os números, esta exibição sozinha economizou cerca de 90 horas de trabalho de qualificação de pilotos.

Aqui repito: Às vezes, algo simples agrega grande valor a um aplicativo. Basta dar uma olhada nessa tela, é basicamente uma lista, um mapa e uma foto. Nada complexo, mas extremamente útil.

Agora vamos para o que representou um desafio um pouco maior, já que eu nunca tinha tido que implementar esse tipo de funcionalidade em um projeto antes.

Você vê, quando você faz rotas em lugares remotos, onde poucas pessoas vivem e são quase intransitáveis ​​(e quase intransitáveis), geralmente não há cobertura de celular. Isso representou um grande problema para o funcionamento do aplicativo durante a competição, uma vez que um grande número de checkpoints estavam localizados em locais dessa natureza.

Dada a existência de PWAs e seu suporte quase out of the box para operação offline, parte do problema foi coberto pelo fato de o aplicativo abrir e exibir algo diferente do dinossauro do Chrome. Porém, simplificando a arquitetura do aplicativo, é um exemplo claro de Cliente - Servidor, que precisa da internet para se comunicar.

Para maximizar a compatibilidade, mantendo o aplicativo simples, usamos localStorage e detecção de conectividade com a Internet do navigator.onLine. Ambas as APIs da Web nativas me ajudam a identificar se o navegador está offline e salvar os dados em localStorage para enviar ou receber atualizações de dados uma vez online.

Com isso finalizamos o desenvolvimento que permitiu que o Rally ADV NL em sua edição de 2022 e o Rally ADV Querétaro 2022 tivessem um grau de automação muito alto a nível operacional.

Considero o NorthBikers um aplicativo finalizado que foi testado em produção, algo que nenhum outro projeto havia alcançado.

Você sabe que outro detalhe não tinha conseguido? Monetize seu próprio aplicativo. Anteriormente, ele cobrava por desenvolvimentos personalizados para pequenos e grandes clientes, sobre os quais eu poderia falar em outro artigo. Mas esta foi a primeira vez que uma ideia minha se materializou e teve uma culminação bem sucedida.

Como esse aplicativo foi monetizado?

1- Indiretamente: Fazia parte de um pacote publicitário que ofereci aos meus patrocinadores.

2- Diretamente: Em seu modo Software as a Service, seu uso era cobrado por evento.

Chaves para terminar bem

A primeira chave é analisar a operação, principalmente aquela que leva mais tempo para ser feita (exemplo: o processo de contabilização de pontos) e conceber formas de automatizá-la através de software.

Usar tecnologias e APIs simples (por exemplo, APIs localStorage e navigator) para atingir seu objetivo também é uma maneira de avançar mais rapidamente no desenvolvimento. O uso de tecnologias externas e mais robustas geralmente exigirá mais investimento de tempo.

Esta fase 3 exigiu uma quantidade maior de trabalho. Geralmente, esses estágios de detalhamento são os menos gratificantes, pois não são alcançados avanços visíveis como resultado. Constância e disciplina são fatores muito importantes neste momento para não desistir e concluir com sucesso seu desenvolvimento.

Conclusão

Manter tudo simples no início, assim como ficar dentro de um núcleo de funcionalidades (apenas funcionalidades essenciais) ajuda muito a focar no que é realmente importante para que o desenvolvimento não demore desnecessariamente.

Ao identificar as necessidades de forma eficiente, uma vez que o núcleo é implementado, você pode identificar como outras pessoas usam seu aplicativo e o que podem estar faltando (ou até mesmo extras). Muito provavelmente, se você perguntar qual funcionalidade o aplicativo deve ter, o que eles responderão não será o que eles realmente precisam. Preste atenção ao que gira em torno dele para identificar esses requisitos.

Acerte na trilha no final – Esta é talvez a coisa mais difícil de fazer quando suas energias e entusiasmo se esgotam, quando não há nenhuma nova funcionalidade para implementar, bem como quando você precisa polir seu aplicativo para ser adequado para uso em produção.

Combinar sua paixão e profissão não é fácil, mas quando dá certo, é uma das melhores satisfações que você pode receber nessa carreira.