- Blog ➔
- Programação ↴
Musclog: Aproveitando minha experiência com React.js para criar um App em React Native
De Bodybuilding para Codebuilding: Criando um aplicativo de fitness completo usando React Native e Expo
Escrito em 21 de setembro de 2024 - 🕒 18 min. de leituraEu constantemente tenho aquela sensação de ”Você se torna aquilo que jurou destruir” devido ao tempo que tenho dedicado ao bodybuilding nos últimos dois anos. Tenho acompanhado meus macros, meus treinos e até tirado fotos de “brogress”.
Não que eu tivesse algo contra o bodybuilding no passado, mas já tentei malhar antes e nunca realmente me envolvi. Sempre senti que eu era um skatista de coração e que estava traindo meu verdadeiro eu levantando pesos. Eu sei, bobo.
Enfim, tenho usado uma combinação de aplicativos e integrações para monitorar meu desempenho, incluindo um script Node.js personalizado para calcular meu TDEE e calorias médias usando a Google Fit API, mas como o Google Fit será descontinuado em breve em favor do novo Health Connect, não pude adiar mais o desenvolvimento do meu próprio aplicativo. Afinal, eu “sai de casa e comi pra caralho!”, então agora vai!
Mas como? Eu honestamente não tinha ideia de por onde começar, especialmente ao explorar integrações com a API de outro aplicativo. Eu nem sabia em qual formato esses dados estariam disponíveis. Qual é o padrão do mercado? JSON? XML? Binário? Eu não tinha ideia. Felizmente, descobri que algumas pessoas realmente inteligentes criaram uma biblioteca para integrar a API do Health Connect com React Native, e saber disso foi o ponto de virada para eu começar a desenvolver meu próprio aplicativo.
A solução perfeita
Eu criei todos esses scripts e integrações para monitorar meus treinos e nutrição, porque uma coisa que descobri nesses últimos anos de bodybuilding é que o que realmente me ajuda a ser consistente é monitorar tudo. Eu sou um cara de dados, e se eu puder ver meu progresso nos números, isso me motiva a continuar. Até porque, a verdade é que se você não toma nenhum anabolizante, o progresso é lento, e eu, pelo menos, não vejo nenhuma diferença no espelho, então os números são tudo o que eu tenho.
Eu já faço o rastreamento de tudo que como há dois anos, e também me peso com uma balança que mede meu percentual de gordura, então tenho muitos dados para analisar e identificar meus padrões de alimentação e treino. O que eu quero é algo que realmente é difícil de encontrar, porque a maioria dos apps ou sites que existem por aí não espera que alguém seja tão meticuloso a ponto de rastrear tudo todos os dias de forma obsessiva, mas eu amo fazer isso.
Então, a primeira ideia era simplesmente obter os dados e continuar meus cálculos com meus scripts, e assim nasceu a ideia do meu primeiro MVP.
O MVP
Como eu disse, tudo o que eu queria era acessar os dados do Health Connect e obter meus dados de nutrição e peso, para que eu pudesse continuar executando meu script Node.js, mesmo que eu tivesse que ter um aplicativo simples que obtivesse os dados em segundo plano e os enviasse para o meu servidor. Parece um plano, certo?
Bem… parece que o Health Connect só permite que os desenvolvedores acessem dados dos últimos 30 dias devido a preocupações com a privacidade. Ok… então isso significa que não posso obter meus dados históricos, e tudo o que está no Google Fit será perdido para sempre. Incrível!
O Verdadeiro MVP
Legal, então nosso MVP morreu antes de chegar à costa; hora de pivotar: E se, em vez de ter um script Node.js que se conecta a diferentes APIs, eu pudesse ter um aplicativo React Native que fará a maioria das coisas, como rastreamento de treinos, insights de nutrição, cálculo de TDEE, gráficos, dicas, etc., e qualquer outro dado que possa estar faltando, eu obtenho da API do Health Connect? Eu poderia até adicionar uma opção para importar dados passados de um arquivo JSON. Dessa forma, se o Google Fit eventualmente permitir que eu exporte meus dados, posso importá-los para o meu aplicativo.
Na verdade, já passei de aplicativo em aplicativo no passado, tentando encontrar a melhor maneira de monitorar meus treinos. Até tentei o Google Planilhas, mas a UX era horrível no celular, e eu gostaria de me concentrar no meu treino e não me estressar com tocar a célula errada na planilha.
Então, React Native, hein?
Claro, eu sabia que o React Native existia, mas como desenvolvedor React.js, nunca considerei realmente mergulhar nele, mas certamente não poderia ser tão difícil, certo? Quer dizer, eu já conhecia o React, então quão diferente poderia ser?
Bem…
Acontece que construir um aplicativo React Native quando sua única experiência é com React.js é como tentar mudar de um skate para uma prancha de surfe. Claro, os princípios são um pouco semelhantes—equilíbrio, navegação, manter a calma quando as coisas dão errado, mas o meio é totalmente diferente. Neste caso, o meio envolvia descobrir como lidar com todas as peculiaridades específicas do dispositivo enquanto mantinha o aplicativo funcional e responsivo.
Por exemplo, como desenvolvedor web, eu foco em manter um estado local no cliente e obter dados do servidor quando necessário, mas no React Native, quero ter um banco de dados local, como devo fazer isso? Bem, descobri o AsyncStorage, então por que não usá-lo por enquanto? (isso vai me morder mais tarde)
Ainda assim, eu não tinha ideia de onde começar, mas após conversar com meus amigos Juampi e Raf sobre minha ideia, eles sugeriram que eu usasse o Expo, um framework que permite construir aplicativos React Native sem ter que lidar com a parte nativa das coisas. Isso foi honestamente um divisor de águas para mim porque eu poderia simplesmente executar meu aplicativo no navegador a maior parte do tempo e usar meu telefone apenas para testar os recursos que exigem código nativo.
Explorando o Expo
Comecei criando um novo projeto Expo seguindo o tutorial ”Crie seu primeiro aplicativo”, e então criei uma nova tela com um botão simples que se conectaria à API do Health Connect e obteria meus dados de nutrição, e lá estava eu, já tinha meu primeiro MVP feito, mas como eu não gosto muito de testar no meu telefone, copiei basicamente a resposta JSON da API e a salvei em um arquivo, para que eu pudesse continuar desenvolvendo apenas no meu computador e navegador—isso vai me morder mais tarde².
Depois de brincar com o Expo por um fim de semana, tive uma ideia vaga do que eu precisava para o meu aplicativo:
- AsyncStorage para armazenamento
- react-native-paper para a interface do usuário
- i18next para traduções
- react-native-charts-wrapper para mostrar gráficos
- @shopify/flash-list para renderizar listas (basicamente só por causa desta palestra eu fui convencido)
Hora de colocar as mãos calejadas para trabalhar!
A alegria (e dor) de aprender na prática
Conforme eu me aprofundava no mundo do React Native, percebi rapidamente que minha caixa de ferramentas confiável do universo React.js, bem, não era totalmente adequada para o trabalho. Para começar, meu esquema de banco de dados era muito complexo para o AsyncStorage, então, pensei, por que não mudar para IndexedDB? Spoiler: IndexedDB só funciona na web, não na versão móvel do aplicativo Expo. Oops.
Depois de algumas horas perdidas tentando implementar um polyfill para IndexedDB no React Native, simplesmente desisti e me vi no meio de uma grande refatoração. Decidi mudar para expo-sqlite
, uma solução de banco de dados local adequada para dispositivos móveis. Mas aqui está o truque—eu ainda precisava do Dexie.js (uma camada para IndexedDB) para manter a versão web funcional enquanto eu desenvolvia o aplicativo, já que uso principalmente o navegador para isso.
Felizmente, a equipe por trás do Expo realmente pensou em tudo: apresento os arquivos .web
no Expo—essencialmente, o Expo permite criar arquivos específicos para a plataforma (como database.ts
e database.web.ts
) para que você possa ter diferentes implementações para web e dispositivos móveis. Isso foi uma salvação, e depois dessa descoberta, posso confirmar que refatorar código enquanto murmura “antes tarde do que nunca” é totalmente uma coisa.
E não podemos esquecer os gráficos—porque o que é um aplicativo de fitness sem gráficos de progresso legais, certo? Bem, o react-native-charts-wrapper
funciona muito bem no celular, mas não na web, então tive que trazer o react-chartjs-2
para a versão web. Você pode ver aonde isso está indo: lidar com duas bibliotecas de gráficos diferentes, dependendo da plataforma, foi apenas mais uma parte da diversão.
A essa altura, eu estava bem fundo nesse buraco de coelho, e para facilitar um pouco a vida, adicionei algumas ferramentas de desenvolvedor ao aplicativo, como funções de exportação e importação de banco de dados. Isso permitiu mover dados entre a web e o celular durante o desenvolvimento. Foi por volta dessa época que percebi por que as pessoas são tão apaixonadas pelo Firebase—talvez em uma versão futura, eu faça a troca, mas por enquanto, o Musclog é 100% offline.
Novas funcionalidades
O desenvolvimento de software é muito parecido com o bodybuilding, você começa com um plano, mas depois descobre que tem genética ruim para os bíceps, e acaba pivotando e fazendo 28 séries para bíceps por semana (certo, pessoal?). Minha visão original era bem simples: apenas um lugar para registrar meus treinos e nutrição. Mas como o Bambam diria, “Tá saindo da jaula o monstro!”, e as funcionalidades começaram a crescer.
E o rastreamento de nutrição? Bem, não é só sobre registrar refeições. Eu precisava ser capaz de adicionar alimentos, diferentes macros, monitorar calorias e integrar tudo isso com os dados de treino. À medida que fui adicionando recursos, percebi que estava usando o GPT para obter informações nutricionais. Então, por que não integrá-lo ao aplicativo? Foi assim que o Musclog acabou com um recurso de chatbot. Agora, posso perguntar coisas como “Quantas calorias tem uma banana?” e obter uma resposta rápida. Mas não vamos nos precipitar.
De rastreamento para chatbots
Então, aqui estava eu, lidando com registros de treino, monitoramento de nutrição e gerenciando múltiplos componentes para diferentes plataformas, e ainda decidi adicionar um pouco de ✨IA✨ na mistura? Afinal, todo mundo adora um bom chatbot hoje em dia, e se você me conhece, oh garoto, eu gosto de um chatbot—tanto que passei centenas de horas codificando uma extensão de chatbot para Magento que por muitos anos foi meu projeto de código aberto mais popular.
Comecei adicionando uma interface de chat simples ao aplicativo, onde os usuários podiam fazer perguntas como “Qual é uma boa refeição pós-treino?” ou “Como posso melhorar minha forma no supino?“. A ideia era criar um treinador pessoal com IA que estivesse sempre disponível, pronto para fornecer insights e dicas.
Como de costume, depois de muitas horas de codificação, decidi mostrar meu progresso para meus amigos, e eles disseram, “Por que não usar Gifted Chat para isso?“. Espere, você está me dizendo que após implementar uma interface de chat do zero, enviando e analisando mensagens, eu poderia simplesmente ter usado uma biblioteca? Bem, acho que essa é a beleza de aprender na prática.
Integração com OpenAI
Integrar o OpenAI ao Musclog foi uma escolha óbvia para mim. Eu já tinha experimentado com isso em outros projetos, como quando usei o OpenAI para criar automaticamente tutoriais de codificação para Instagram Reels. Com essa experiência, eu já estava familiarizado com chamadas de função, análise de respostas e manipulação de prompts. Então, pensei, por que não adicionar essa ferramenta poderosa ao meu aplicativo?
A integração em si foi bastante simples. Usei a API do OpenAI para processar as consultas dos usuários e fornecer respostas perspicazes. Toda vez que um usuário envia uma mensagem, o histórico do chat é enviado de volta ao OpenAI para manter o contexto da conversa intacto. Para dar um pouco de personalidade à IA, usei mensagens do sistema como, “Você é um treinador pessoal prestativo chamado Chad, e está aqui para ajudar nas jornadas de fitness. Pergunte-me qualquer coisa!”
Mas não parou por aí. Eu imaginei que, se já estava integrando o OpenAI, por que não ir um passo além? Então, adicionei uma opção para pedir ao OpenAI que criasse um plano de treino diretamente. Por exemplo, você pode usar o chatbot para perguntar, “Você pode criar um treino de push-pull-legs para mim?” e pronto—Chad, o treinador, entra em ação, gerando uma rotina de treino personalizada na hora. Este recurso é particularmente útil quando você não tem certeza de como estruturar seu treinamento ou se está procurando variar sua rotina.
As possibilidades aqui são bastante empolgantes. Com essa integração, o Musclog não é apenas um rastreador de treino estático; ele se torna um treinador de fitness dinâmico que evolui com suas necessidades. E sejamos honestos, ter uma IA que pode criar um plano de treino em segundos parece um superpoder, especialmente quando você está na academia e precisa de uma rotina rápida no momento.
Não só isso, mas também dei acesso a todas as informações de saúde ao OpenAI, então meus dados de nutrição, treinos, peso e porcentagem de gordura estão disponíveis para a IA usar, para que ela possa me fornecer melhores insights. Claro, devido a preocupações com a privacidade, tornei isso opcional, e também adicionei um recurso para excluir todos os dados sempre que o usuário quiser. Mas imagine, fazer um treino realmente difícil e depois perguntar ao GPT o que ele acha sobre isso, bem legal, né?
Design do App
Eu não sou designer, mas gosto de pensar que tenho um bom olho para UI/UX por causa de muitos anos de desenvolvimento web. No entanto, o desenvolvimento móvel foi uma fera completamente diferente, então precisei terceirizar os designs de UI e qualquer arte, usando recursos gratuitos de código aberto ou IA.
Sim, sim, eu sei de todo o ódio em relação à arte gerada por IA, mas era isso ou arte feita no MS-Paint, então optei pela arte gerada por IA.
UI
Para a interface do app, usei componentes do react-native-paper, o que facilitou a criação de um visual limpo e moderno, com a maioria dos componentes de que eu precisava, como botões, cartões e modais.
Isso resolveu o lado funcional das coisas, mas e a parte estética? Eu terceirizei meus esforços para o v0, uma ferramenta da Vercel que usa IA para gerar aplicações simples de uma página para serem usadas em um app Next.js. Eu simplesmente inseri o texto explicando o que precisava e pedi que fosse mobile-first, e voilà, eu tinha um design lindo para o meu app.
Logotipo e ilustrações
Para o logotipo e as ilustrações, usei o DALL-E da OpenAI para gerar as imagens. Eu simplesmente digitei o texto explicando o que precisava e detalhes sobre o meu app e obtive alguns resultados bem legais. Depois, usei o Photopea para fazer alguns retoques e adicionar efeitos às imagens.
Chegando na Google Play
Depois de meses de desenvolvimento, testes e uma quantidade não saudável de Pepsi Max, o Musclog estava finalmente pronto para o grande palco: Google Play. Mas é aqui que as coisas ficaram… interessantes. Eu estava sob a impressão de que poderia simplesmente enviar meu aplicativo e pronto, como fiz em 2019 para meu jogo Gotinha. Ha! Mal sabia eu que o Google Play força você a conseguir 20 pessoas para testar seu aplicativo antes de ele ser lançado, mesmo que você seja apenas um desenvolvedor solo. WTF, certo?
Encontrar 20 pessoas para testar seu aplicativo parece fácil até que você realmente faça isso. Acabei recrutando qualquer um e todos—amigos, família, colegas de trabalho, conhecidos em festas, talvez até tenha pedido a alguns estranhos na rua (brincadeira, talvez). Mas após reunir meus “bros” de teste e passar pela fase inicial de testes, adivinhe o que aconteceu? Meu aplicativo foi rejeitado. Sim, é como se a vida simplesmente não estivesse pronta para me deixar vencer.
Então, lá estava eu, esperando mais 14 dias, corrigindo os problemas que eles apontaram e reenviando o aplicativo. Foi uma montanha-russa de emoções, para dizer o mínimo. E como se isso não bastasse, porque eu queria a integração com o Health Connect, mas não só isso, acredite ou não, eu também precisava ter um site público para o meu aplicativo, então tive que criar um site para ele, escrever uma política de privacidade e preencher um formulário explicando por que precisava de acesso aos dados do Health Connect. Então, criei rapidamente um site usando Next.js e https://v0.dev/, e usei o GPT para escrever uma política de privacidade para mim, você pode vê-la aqui: https://blopa.github.io/musclog-website/.
Você pode estar se perguntando se eu fiz este aplicativo para mim mesmo, por que me importo em tê-lo no Google Play? Bem, por um lado, acho que o Google Play é bastante conveniente e quero conveniência ao instalar o aplicativo no meu telefone, e em segundo lugar, quero compartilhá-lo com meus amigos e familiares, e acho que é mais fácil compartilhar um link para o aplicativo no Google Play do que enviar um arquivo APK.
Mas depois de todos os obstáculos, recebi finalmente o sinal verde, e o Musclog estava oficialmente no Google Play. Então, sim, não foi fácil, mas definitivamente valeu a pena. “É hora do show, porra!”
Tornar-se open-source ou não
Eu sempre libero todos os meus projetos como código aberto—é meio que minha coisa. Mas quando se tratou do Musclog, eu hesitei. Este aplicativo me levou mais de 300 horas para desenvolver, e tem alguns recursos realmente interessantes que não vi em outros aplicativos de fitness. Achei que talvez pudesse recuperar parte do tempo que gastei nele vendendo-o no Google Play ou talvez adicionando um botão de “me dê uma gorjeta”.
Mas uma vez que meu aplicativo foi aprovado e, para ser honesto, após usá-lo nas últimas semanas, percebi que, embora os recursos e ideias sejam legais, o aplicativo não é tão polido quanto eu gostaria que fosse. Percebi que talvez o Musclog fosse melhor como um projeto open-source, onde a comunidade pudesse me ajudar a melhorá-lo—o que, para ser honesto, também é um desejo, porque a maioria dos projetos open-source não ganha muito destaque e são principalmente mantidos pelo criador, então o melhor que posso esperar é que as pessoas criem issues e peçam recursos. Viva!
Honestamente, meu sonho seria ter um aplicativo open-source que de alguma forma me fizesse ganhar dinheiro—algo como Mindustry ou Blender. Então, depois de limpar o histórico de commits do Git, não porque estou envergonhado do meu código—ok, talvez um pouco—mas principalmente porque não tinha certeza se tinha cometido um erro ao enviar uma chave do OpenAI por engano, decidi tornar o Musclog open-source.
Você pode conferir o código aqui: https://github.com/blopa/musclog-app. Se você gosta de fitness e codificação, sinta-se à vontade para contribuir. Quem sabe? Talvez juntos possamos transformar isso em algo realmente especial.
O que o futuro reserva
Agora que o Musclog está no mundo, já estou pensando no que vem a seguir. Existem muitos recursos que eu adoraria adicionar, como análises de treino mais detalhadas, capacidades de IA aprimoradas e talvez até alguns recursos sociais para compartilhar treinos com amigos ou participar de desafios.
Um “problema” com o Musclog é que ele é realmente um aplicativo para levantadores avançados, não que eu seja avançado (não sou), mas sou louco por dados e monitoramento, e meu aplicativo realmente brilha se você é o tipo de pessoa que monitora cada repetição, série e caloria. Então, estou pensando em criar uma versão mais simples do aplicativo, com menos recursos, ou talvez com um processo de onboarding melhor, para que os iniciantes também possam usá-lo, afinal, a maioria dos levantadores são iniciantes, certo? Eu também gostaria de conseguir convencer meus amigos a começar a malhar e usar meu aplicativo, então preciso torná-lo mais atraente para eles.
Alguns dos recursos que estou pensando em adicionar são:
- Integração com dispositivos BLE
- Capacidades de rastreamento de alimentos no aplicativo
- Análises de treino mais detalhadas
- Opção de usar um modelo OpenAI personalizado
- Talvez um modelo LLM local um dia
- Conta online para sincronizar dados entre dispositivos
- Perfil online para compartilhar treinos e desafios
- Recursos de gamificação
Conclusão
Olhando para trás, a jornada de construir o Musclog foi tanto sobre crescimento pessoal quanto sobre codificação. Aprendi muito sobre desenvolvimento móvel, o que sempre é uma coisa boa. Eu posso ser um desenvolvedor web hoje em dia, mas não foi assim que tudo começou; nos meus dias de faculdade, eu era um desenvolvedor C++, e o desenvolvimento web nem fazia parte do curso, então voltar ao desenvolvimento de plataformas é uma mudança de ritmo agradável.
Então, se você está pensando em iniciar seu próprio projeto—seja um aplicativo, um site ou outra coisa qualquer—meu conselho é simples: apenas faça. Abrace os desafios, aprenda com os contratempos e aproveite o processo. Porque no final das contas, a única coisa que está entre você e seus objetivos é a decisão de dar o primeiro passo.
Obrigado por me acompanhar nesta jornada, e mal posso esperar para ver o que construímos a seguir. Levante, Registre, Repita!
Vejo você no próximo!
PS: Se você quiser experimentar o Musclog, pode baixá-lo no Google Play: https://play.google.com/store/apps/details?id=com.werules.logger.
Mas e o código?
Na verdade, eu queria incluir trechos de código e explicar como a maioria das funcionalidades funciona, mas percebi que isso deixaria o post muito longo. Então, decidi escrever uma série de posts explicando como construí o Musclog. Fique de olho!
Tags:
Posts relacionados
Publicar um comentário
Comentários
Nenhum comentário.