혹시 책을 읽다가 마음에 드는 문장을 발견하거나 구절을 발견해서 밑줄을 긋거나 사진을 찍었던 적 있으신가요?
내가 산 책은 밑줄 긋고, 필기를 할 수 있지만, 빌린 책은 사진을 찍거나 필사를 할 수 밖에 없습니다.
나중에 봐야지 하고 사진을 찍었지만 결국 갤러리 구석 어딘가에 방치된 적 있지 않으신가요?
PagePick은 원하는 책을 바코드로 검색하여 저장하고, 기억하고 싶은 문장이나 사진을 책별로 아카이빙 하는 독서 기록 앱입니다.
https://play.google.com/store/apps/details?id=com.sanghyun01.PagePick
이번 블로그에서는 배포 과정에서 발생한 문제와 험난한 해결 과정에 대해 작성해보고자 합니다.
비공개 테스트 완료까지 2일 남은 시점에서 배포 에러가 터져버렸습니다...
PagePick은 네이버 API로 도서 정보를 가져오고, supabase DB에 도서,문장,사진 등을 저장합니다. 또한 구글 OAuth 로그인을 제공하고 있습니다.
따라서 env 파일에는 NAVER Client ID, NAVER SECRET Key, Supabase URL, Supabase anon key, Google_Web_Client__ID 가 필요합니다.
지금까지 계속 eas 클라우드를 사용해서 빌드를 진행했습니다. 프로젝트의 env 파일은 보안상 gitignore에 포함시키기 때문에 Expo 원격 서버에서 돌아가는 eas 빌드는 로컬의 env를 읽을 수가 없습니다.
따라서 Expo 원격 서버가 읽을 수 있는 eas.json이나 eas secret에 등록해주어야 합니다.
처음에는 eas.json에 등록했고, 성공적으로 빌드와 배포가 되었습니다.
하지만 eas.json은 gitignore에 추가하지 않아 그대로 깃허브에 올라갔고, 시크릿 키와 같은 민감한 정보가 노출되는 것은 보안상 위험할 것이라고 판단하여 새로운 키를 발급받아 교체를 진행하기로 했습니다.
이 결정이 엄청난 고통과 고난과 역경과 삽질을 불러왔습니다😭
아침 8시부터 새벽 3시까지 이어진해커톤.. 아니 디버깅..!
하나씩 고쳐나가다 보니 정확히 어떤 문제 때문에 배포에 실패한 것인지는 파악하기 어렵지만, 가능성 있는 문제 원인들을 나열해보도록 하겠습니다.
새로운 네이버 클라이언트 시크릿, 구글 웹 클라이언트 ID를 발급받고, eas env:create 명령어로 eas secrete에 추가해주었습니다.
❗eas secret에 URL이나 Secret을 추가할 때 주의할 점은 따옴표를 넣지 않는 것입니다.
예를 들어, https://abcd.co 와 같은 URL이 있을 때, "https://abcd.co" 이와 같이 따옴표와 함께 작성하면 시스템이 주소를 문자열 그 자체로 인식하여 따옴표까지 주소로 인식하게 됩니다.
이로인해 서버에 제대로 된 주소를 전달할 수 없게 됩니다.
환경 변수를 교체하고 배포 버전을 설치했을 때, 앱을 실행하자마자 종료가 되는 문제가 발생했습니다.
정확한 에러 원인을 파악하기 위해 adb logcat 명령어로 로그를 확인해본 결과, error invalid supabaseurl must be a valid http or https url 와 같은 에러가 발생했습니다.
secret에 supabase url을 추가할 때 따옴표(' ')를 붙인 것이 원인이였던 것 같습니다.

app.config.ts 는 EAS 서버에 저장된 비밀 값을 앱 코드 안으로 전달해주는 역할을 해줍니다.
eas secret에 환경 변수를 저장할 때, EXPO_PUBLIC을 붙이게 되면 별도 설정 없이 proccess.env.EXPO_PUBLIC_SECRET 으로 바로 접근이 가능합니다.
하지만 제가 처음에 저장했던 방식은 EXPO_PUBLIC을 제외한 방식이었고, 따라서 빌드 서버에만 존재하고, 앱 코드(클라이언트)는 이 환경변수의 존재를 알 수 없었던 것이었습니다.
그래서 app.config.ts 파일을 만들어 환경 변수와 시크릿 키들을 등록해주고, 앱 코드에서는 
Expo.Constants.expoConfig.extra를 통해 값을 사용하도록 했습니다.
수정을 마친 뒤 빌드, 배포하고 구글 콘솔 내부 테스트에 올려 실행을 해봤지만 결과는....
.
.
.
아,,, 그만할까,,, 아니야 이거만 해결하면 출시인데 조금만 더,,,,,,,,,,,,,,,🫠😵💫
eas 클라우드로 빌드를 진행해왔었는데 무료 플랜 사용으로 이번 달 빌드 할 수 있는 한계에 도달했다는 알림을 받고 눈 앞이 캄캄해졌습니다.
이번 달 안에는 출시해야 되는데.. 이제 어떻게 하지?
다행히도, 안드로이드 스튜디오나 로컬에서도 직접 빌드할 수 있는 방법이 있다는 것을 발견했고, 안드로이드 스튜디오로 빌드를 시도했지만, 잘 되지 않아서 결국 로컬에서 빌드를 하기로 했습니다.
우선 android/ 폴더에서 build와 .gradle, .cxx 파일을 지워서 딥 클린을 해준 뒤, 터미널에서 .graldew bundleRelease로 빌드를 하여 aab 파일을 추출해주었습니다.
구글 콘솔에 올려서 검토를 받았는데, 서명키가 다르다는 메시지가 떴습니다.
build.gradle 파일을 확인해보니 SigningConfigs 에 release를 위한 서명 키가 없었고, debug를 위한 서명 키만 있었습니다.
eas credentials로 keystore의 password, keyAlias 등의 값을 찾은 다음 build.gradle에 release에 추가해주었습니다.
마지막으로 버전 코드를 올려준 뒤, 빌드를 하고 구글 콘솔에 올려서 실행해보았지만 또 실패....
더 이상 못하겠다.. 급기야 포기 선언. 그냥 잘래

제미나이 넌 천재야!!
내부 테스트에 업로드하면 구글 플레이에 업데이트 한 버전이 적용되는데까지 시간이 어느정도 걸려서 최종적으로 수정한 버전이 아닌 이전 버전이 설치가 되었던 것이었습니다.
내부 테스트에 올린 웹 참여 링크를 다시 들어가보니 앱에서 업데이트 버튼이 활성화 되어있었고, 업데이트를 한 뒤 실행해보니... 성공!!!!!!!!! (알고보니 내부 테스트에 올리고, 애플리케이션에서 play스토어 저장공간의 캐시를 삭제하고 바로 링크를 들어가보면 업데이트가 활성화 되는것이었습니다)
앱 출시라는 목표를 가지고 두 달 동안 달려온 끝에 목표를 달성할 수 있었고, 처음 앱을 출시하는 과정에서 우여곡절이 많았지만 끝끝내 포기하지 않고, 될때까지 붙잡고 파고든 덕분에 문제를 해결할 수 있었습니다.
현재는 구글 플레이 스토어에 프로덕션 출시가 완료된 상태이고, 앞으로도 기능 추가와 업데이트를 계속 이어나갈 예정입니다!