피트니스 산업과 IT, 그리고 스타트업

IT

바이브 코딩으로 앱 개발 하다가 겪은 병목들

핏더스트리 2025. 6. 13. 12:21

바이브 코딩으로 앱 개발 하다가 겪은 병목들

앱을 개발할 때 가장 많이 듣는 말 중 하나는 “직접 만들어보면 안다”는 말입니다. 이번 프로젝트는 Flutter와 Supabase 조합으로, 백엔드 서버 없이도 앱을 구축할 수 있는 serverless 구조였고, 저는 이걸 오로지 바이브 코딩으로 만들어봤습니다. 즉, 큰 설계 없이 즉흥적으로 구조를 짜고 기능을 붙여가며, 문제가 생기면 즉시 해결하는 방식이었죠.

 

이러한 개발 방식은 빠르게 MVP를 만들어야 할 때는 매우 강력합니다. 하지만 역시나, 처음 겪는 문제에 대한 경험 부족은 병목이 되기 쉽습니다. 이번 회고에서는 전체 개발 기간 중 가장 많은 시간을 소비하게 만든 세 가지 병목 지점을 소개하려 합니다. 단순한 기능 구현보다도, 개발 환경이나 설정에서 시간을 허비한 부분들이 더 크다는 것도 깨달았고요.

 

정리하자면, 오늘 다룰 세 가지 주제는 다음과 같습니다.

 

  1. DB 타임존 문제 – 글로벌 유저를 고려하지 않은 시간 데이터 저장 방식
  2. 맥북 저장 공간 이슈 – 개발 환경 자체가 막혀버리는 상황
  3. 로그인 리다이렉트 설정 문제 – 인증 과정의 작은 변수 차이가 만든 큰 오류

 

이 경험이 저처럼 처음으로 실전 앱을 혼자 만들어보는 개발자분들에게 작은 도움이 되길 바랍니다. 이제 그 첫 번째 이야기부터 시작해볼게요.

 

DB 타임존 이슈, 시간 순서가 거꾸로?

앱을 만들면서 가장 당연하다고 생각했던 것이 바로 시간 데이터였습니다. 채팅 메시지, 게시글, 알림 등 시간 순서대로 쌓이고 보여줘야 할 정보들이 대부분이니까요. 그런데 문제는, 유저의 기기 시간에 따라 DB에 저장되는 시간 정보가 달라질 수 있다는 점이었습니다. 저는 처음에 사용자 디바이스의 지역 시간(Local time)을 그대로 DB에 저장하고 있었고, 그게 문제를 일으킨다는 생각조차 하지 않았습니다.

 

사실 한국에서만 테스트할 땐 문제가 없습니다. 하지만 이 앱을 들고 미국으로 여행을 갔을 때 문제가 본격적으로 발생했죠. 같은 앱인데, 메시지가 시간 순서가 뒤죽박죽으로 쌓이기 시작한 겁니다. 처음엔 Flutter 코드나 Supabase 설정을 의심했지만, 근본적인 원인은 ‘시간 저장 기준’에 있었습니다.

 

DB는 지역 시간 정보를 기준으로 삼는 것이 아니라, 절대적인 기준 시각인 UTC (Coordinated Universal Time) 으로 통일해 저장하는 게 맞습니다. 그래야 사용자의 지역이나 디바이스 환경에 상관없이 데이터의 시간 순서가 유지됩니다. 예를 들어 한국과 미국 사이의 시차가 13시간이라면, DB는 이를 UTC로 환산해 저장하고, 클라이언트에서는 그 값을 받아 사용자의 지역 시간으로 다시 변환해 보여주는 방식이어야 하죠.

 

이건 사실 대부분의 서비스에서 당연하게 쓰는 방식이지만, 저는 처음으로 글로벌 타임존 이슈를 체감해본 터라 꽤 오래 삽질을 하게 됐습니다. 특히 Supabase나 PostgreSQL에서 기본 시간대 설정이 어떻게 되어 있는지를 명확히 이해하지 못한 상태에서 무작정 로직을 짜다 보니, 클라이언트와 서버 간의 시차가 데이터를 엉망으로 만들어버렸던 겁니다.

 

결국 해결책은 간단했습니다. DB에는 UTC 시간으로만 저장하고, 사용자에게 보여줄 땐 intl 패키지 등을 활용해 지역화된 시간으로 변환하는 것. 단순한 규칙이지만, 이걸 명확히 이해하고 미리 적용하지 않으면 글로벌 서비스에서 큰 혼란을 겪을 수 있습니다.

 

 

맥북 용량 이슈

두 번째 병목은 굉장히 기초적인 문제였지만, 오히려 그래서 더 당황스러웠습니다. 바로 맥북의 저장 용량 부족 문제입니다. Flutter로 앱을 개발하는 경우, 에뮬레이터를 띄우거나 빌드를 수행할 때 상당한 저장 공간을 사용하게 되는데, 저는 이 사실을 간과하고 있었던 거죠.

 

프로젝트가 어느 정도 덩치를 키우기 시작하자, 에뮬레이터가 갑자기 실행되지 않기 시작했습니다. 처음엔 코드가 잘못된 줄 알고 디버깅을 하다가, 단순히 디스크 공간이 부족해서 Flutter가 빌드 캐시를 생성하지 못한다는 걸 알아차리는 데 꽤 시간이 걸렸습니다. 그제야 ‘개발도 결국은 환경의 제약 안에서 이뤄진다’는 기본을 실감하게 되었죠.

 

Cursor 같은 IDE는 빌드 캐시를 자동으로 비워주는 기능이 있어서 초기에는 이 점에 크게 신경을 쓰지 않았습니다. 하지만 문제는 빌드 캐시만이 아니었습니다. 제가 iCloud 동기화를 켜둔 상태였고, Flutter 프로젝트 폴더가 자동으로 클라우드에 업로드되면서 생긴 문제가 또 하나 있었습니다. 스토리보드 파일들이 iCloud에서 내려오면서 확장자가 .xml로 바뀌는 버그가 생겼던 거예요. 이로 인해 iOS 빌드가 또 깨졌고, 해결에 제법 시간이 걸렸습니다.

 

더불어, Flutter 프로젝트 내에는 .dart_tool, build, .idea, ios/Pods 같은 무거운 디렉토리들이 꽤 많은데, 이걸 주기적으로 지우지 않으면 어느 순간 개발 자체가 불가능한 수준으로 저장 공간을 차지하게 됩니다. 특히 Mac 환경에서는 개발자들이 앱 테스트에 사용하던 시뮬레이터 이미지, Xcode 캐시 등도 저장소를 압박하죠.

 

이런 경험을 통해 얻은 교훈은 명확했습니다. 개발 환경도 정기적인 관리가 필요하다는 점입니다. 특히나 용량이 적은 노트북에서 Flutter 같은 프레임워크를 쓸 때는, 캐시 정리나 클라우드 저장소 설정 등에 더 민감해져야 한다는 걸 절실히 느꼈습니다.

 

 

소셜 로그인 구현

세 번째로 마주친 병목은 앱 개발자라면 누구나 한 번쯤은 겪게 되는 인증 기능 구현입니다. 이번 프로젝트에서는 Supabase를 통해 소셜 로그인 기능을 구현하려 했는데요, 표면적으로는 몇 가지 설정만으로 간단하게 붙일 수 있을 것처럼 보였습니다. 하지만 현실은 예상보다 훨씬 복잡했죠.

 

처음에는 네이티브 방식으로 로그인 기능을 구현하는 대신, 웹 리다이렉트를 활용한 방식이 더 간단해 보였기 때문에 그쪽을 선택했습니다. 그러나 예상과 달리 모바일 환경에서는 이 방식이 매끄럽게 작동하지 않았습니다. 특히 앱을 백그라운드로 전환했다가 다시 복귀하는 흐름에서 리다이렉트가 제대로 이어지지 않거나, 세션이 중단되는 문제가 발생했죠.

 

게다가 Supabase에서 제공하는 인증 설정 화면과 각 소셜 로그인 서비스(특히 Apple)의 명칭이 서로 다르다는 점도 혼란을 줬습니다. 예를 들어 Supabase에서는 Client ID를 입력하라고 요구하는데, Apple Developer Console에서는 비슷한 개념의 값들이 App ID, Service ID 등으로 구분되어 있었습니다. 이 용어의 차이 때문에, 저는 처음에 잘못된 값을 입력하여 인증이 제대로 되지 않았고, 이 오류를 찾는 데 적지 않은 시간이 소요됐습니다.

 

결국 이 문제는 ‘경험’이 해답이었습니다. 문서를 읽고 가이드를 따라가도 용어가 다르면 실수가 생기기 마련이고, 다양한 실험과 시도를 통해 실제 작동하는 조합을 찾는 데 시간이 꽤 걸렸습니다. 인증은 앱의 핵심 기능 중 하나이기 때문에, 동작이 불안정하면 전체 사용자 경험에도 영향을 미칩니다. 그래서 지금 생각해보면, 차라리 처음부터 네이티브 방식으로 정공법을 택했으면 어땠을까 하는 아쉬움도 남습니다.

 

supabase auth provider settingapple developer account

 

마치며...

이번 앱 개발 과정에서 겪은 병목들은 단순히 코드의 문제가 아니라, 환경, 설정, 경험 부족 등 개발자의 ‘현실적인 조건’에서 비롯된 경우가 많았습니다. Flutter와 Supabase는 굉장히 효율적인 조합이었고, 적은 리소스로도 강력한 기능을 가진 앱을 만들 수 있는 훌륭한 도구였지만, 작은 설정 하나, 캐시 하나, 용어 하나가 큰 발목을 잡기도 했죠.

 

이런 시행착오를 통해 얻은 교훈은 명확합니다. 기술적인 역량 못지않게 환경을 이해하고, 예상치 못한 상황에서 빠르게 대처하는 능력도 중요하다는 것입니다. 앞으로 또 다른 프로젝트를 시작하더라도, 오늘 이 회고에서 정리한 병목 세 가지는 분명 도움이 될 거라 믿습니다.

 

지금도 Flutter나 Supabase로 프로젝트를 진행 중이시라면, 혹은 이제 막 시작하려는 단계에 계시다면, 저처럼 삽질하지 않도록 이 글이 작은 힌트가 되었으면 좋겠습니다.

반응형