SnapPal 개발 회고

OrganCow·2024년 11월 8일
0

RN기반 SnapPal 개발 회고 겸 개발 과정 발생한 이슈를 두서없이 정리
글 보러가기
AppStore - SnapPal 보러가기

개요

사진 기반 펜팔 앱을 Expo RN + Supabase로 개발함.

회고 및 레슨런

1. 유저 기반 앱은 사람들 밀어넣을 전략 만들고 출시해야함.

  • 호기심에 설치했더라도 조용하면 쉽게 이탈.
  • 하나씩 팔려도 상관없는 유틸성 앱과 접근을 다른 접근 필요.
  • 넘 당연한건데 ㄱ-

2. 홍보가 개발보다 어려웠음.

  • 안해봐서 그럼.
  • 모든 게 처음이라 다양한 채널로 시도하면서 몸으로 배우는 중.

3. 초반 과한 국제화는 짐이다.

  • 한국어 / 영어로만 시작 후 반응보고 해도 늦지 않음.
  • 번역도, 배포도 고역이 됨.

4. Supabase DX 훌륭함.

  • FE개발자인데도 배치, 스케쥴링, 인증/인가, 스토리지, DB 까지 쉽게 개발
  • 모든 걸 서버리스로 하려다보니 DB - 서버 역할 구분이 애매해짐.

5. Expo 꽤 좋아짐

  • 플러터나 Supabase처럼 wow는 아니지만 웬만한 건 다 있음
  • 빌드는 여전히 느림

6. 좋은 서비스가 있더라도,

  • DB, 서버 잘 알아야함.
  • 아래 개발 이슈의 대부분이 DB, 서버 잘 몰라 발생함
  • 좋은 경험이었음.

7. 체력과 개발 퀄리티

  • 1인 개발에서 체력 안배는 중요함.
  • 뭐라 할 사람도 없으니 피곤하면 대충 뭉개며 짰다가 괴로워하길 반복.

✱ 믿고 응원해준 여자친구와 구매해준 사람들께 감사함. 신기한 경험이었음.

개발 이슈

1. Trigger ? Webhook ?

  • 둘 다 DB 변경사항에 반응해 액션을 취할 수 있는 기능.
  • Webhook은 외부 요청을 편하게 하기 위한 Trigger의 wrapper.
  • Webhook은 POST요청의 body를 변경할 수 없으며 Supabase Edge Functions 혹은 HTTP 요청 가능.

✱ Trigger로 DB 조작하면 트랜잭션이 안걸린다. 트랜잭션 필요하면 rpc(프로시저)를 써야했는데, 백엔드 개발자가 아니다보니 하나의 작업을 트랜잭션 없이 해야하는 상황이 있는지 모르겠음.

2. rpc ? SDK ?

Supabase SDK 클라이언트단에서 쉽게 DB에 접근 및 조작이 가능.
✱ 마찬가지로 백엔드 개발에 친숙하지 않아 어디까지 SDK를 이용하고 어디서부터 프로시저 처리하는지 애매했음.

3. RLS

  • 설계 시 서비스 고려해서 잘 설정해야함.
  • 쿼리 RLS 위반 시 에러를 뱉는 게 아니라 빈 행을 반환해 디버깅에서 한참 애먹음
  • 익숙하지 않아 힘들었음. 잡아둔 RLS와 필요한 쿼리가 부딪혀 조회가 안되는 상황 발생.
  • 권한을 잘못 설정했다기보다는 테이블 설계 미스였던 걸로 생각됨.

4. 이미지 캐싱

  1. expo-imagecachePolicy만 믿고 있었음. url을 키로 캐시처리함.
  2. Supabase는 만료되는 signedUrl를 이용해 비공개 이미지 접근을 핸들링함.
  3. 매번 url이 변경됐고 다른 key로 캐싱하는건 expo-image가 미지원.

✱ 결국 이미지의 id를 key로 캐싱하는 로직을 구현했음.

5. IOS 심사 정책

  • 전화번호(타 민감 개인정보 동일)를 필요로 하는 앱이 아니면 전화번호 로그인 불가.

✱ 개발 초기에 알아서 금방 되돌렸다.

6. Expo Camera와 IOS 카메라 인디케이터

  • 화면이 넘어가 expo-camera 컴포넌트가 언마운트되도 IOS의 카메라 인디케이터(녹색 불)가 꺼지지 않는 이슈
  • https://github.com/expo/expo/issues/16404
  • 꽤 오래된 이슈인데 여전히 해결 안 됨.

✱1. expo-routeruseFocusEffect() 훅으로 명시적 unmount 해줘 해결.

if (!isScreenFocused) {
	return null
}

✱2. issue탭 내용으론 이걸로 안되는 사람들도 있는 듯.
✱3. Expo Go 말고 프로덕션 빌드에서 해결되기도 하는 듯.

7. 이미지 재요청

  • 사진 앱이니 이미지 안 뜨면 곤란함.

✱ 오류 발생 시 3초 간격으로 재요청하도록 에러 처리

const onError = (event: ImageErrorEventData) => {
    const now = Date.now();
    if (now - lastErrorTimeRef.current < RETRY_DELAY) return; // 3초당 한 번씩만 실행

    if (retryCount < MAX_RETRIES) {
      lastErrorTimeRef.current = now;
      setTimeout(() => {
        setRetryCount((prevCount) => prevCount + 1);
      }, RETRY_DELAY);
    } else {
      // RETRY_COUNT 초과
      console.error(event.error);
      setIsLoading(false);
      setError(event.error);
    }
  };

8. 비정규화

✱ 계속 그렇듯이 DB에 미숙해 애매했던 지점.
✱ 자주 요청하는 쿼리에 join이 필요한데 최적화 위해 updatedAt 컬럼을 중복해서 둠.

안티패턴일까?

9. expo-router의 dynamic route와 replace

  • /chats/[chatId]/detail/[photoId]
    이런 경로에서 replace()를 실행해도 경로가 제대로 안날아가고 남아있는 버그가 있었음.

replace전 현재 path 조회해 dismissAll() -> 필요한 페이지로 push 중첩하는 식으로 처리
✱ 버그가 아니라 dynamic route 겹치지 말라는 걸 얼핏 본 거 같기도 하다.

10. 랜덤발송 알고리즘

  • 펜팔이 랜덤으로 전송되도록 하기 위한 고민.
  • 최대한 골고루 분배하기 위해 random 함수보다 나은 방법을 원했고

✱ 가중치 알고리즘은 과하다 생각해 last_received_at 컬럼을 두어 안 받은게 오래 된 순으로 뿌려줌.

  • last_activity_at 컬럼을 두고 일주일 간격 배치 처리로 비활성 유저를 분배 리스트에서 제외

11. 탈퇴 유저 Soft Delete

  • 사진 관련 앱이니 유해 콘텐츠 관리가 중요.
  • 신고 내역 확인 전에 탈퇴해버리면 찾기 힘듬

✱ soft delete 처리하고 일주일 간 신고 내역 없으면 삭제하는 식으로 구현

12. 에러 메세지 보안

  • 버그 문의 대응을 위해 raw 에러 메세지를 보여주는 식으로 구현했는데
  • 이것 자체가 보안 위협임을 깨달음.

✱ prod / dev 환경 구분해 에러 메세지 처리(앞으로)
✱ prod는 로그로만 남긴다.

13. supabase rpc내 truncate 권한

  • Edge Functions 내에서 실행하는 배치 rpc에 truncate가 포함.
  • RLS가 테이블에 걸려 있음에도 불구하고 일반 사용자가 rpc사용 시 truncate가 실행되는 문제 발생

✱ 원래 그런건지는 모르겠음. rpc내에서 권한 체크 후 에러 던지는 식으로 대응

14. Edge Functions(AWS lambda) 국제화

✱ i18n을 콜드스타트마다 받을 수 없으니 translate 함수 구현
✱ 번역문을 DB에 담아둘까 하다가 함수 메모리에 올리고 사용했는데,뭐가 나은 방식일지는 테스트 못해봄.

15. 하나의 유저가 여러 기기 설치 시 push token 관리

✱ token 테이블을 profile 테이블과 따로 두어 관리
✱ push 알림 전송 시 유저의 모든 토큰 조회

16. push notification 유저 액션 대응

  • refetch 관리 필요했음.

✱ 유저 시나리오를 정리하고 이에 맞게 구현

  1. 앱 내부에 있을 때 알림
    • 화면 A에 있을 때 / 그렇지 않을 때
  2. 앱 background 실행 중
    • push 알림 눌러 진입 / 앱 전환기능으로 진입
  3. 앱 실행 중 아닐 때 push 알림 통해 진입

17. IOS 권한 허용 문구 i18n

  • 레슨런에 적은 대로 체력 이슈로 방법을 찾지 못했다.
  • 그냥 영어로 퉁쳐버림

18. 구글 로그인, 안드로이드 푸시 알림 뭐 이리 복잡한지

  • 매 번 바뀌어 문서도 뒤죽박죽인 느낌

19. PlayStore 심사가 이제 만만하지 않다.

  • 비공개 테스트 20명...?

20. 안드로이드는 배지 count를 기본적으로 제공하지 않는다.

  • 서드파티앱으로 하는 걸로 확인

소요시간

  • 25분 뽀모도로 223회 🍅 (약 85시간)
  • 한 달 가량 소요
  • 287 커밋

0개의 댓글

관련 채용 정보