Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

SmartMirror Controller

스마트 미러 🌐를 제어하기 위한 모바일 앱입니다.
스마트 미러는 현재 위치의 온도, 날씨, 미세먼지 레벨, 앱에서 지정한 측정소의 미세먼지 레벨, 날씨, 시간별 메세지, 앱에서 정한 사진을 표시해 줍니다.

미러 사진 바꾸기-0001 image

1. 제작 기간

  • 2022.08 ~ 2022.08 (개인용)
  • 2023.04 ~ 2023.05 (TypeScript 적용 및 배포용)

2. 사용 기술

공통

  • Firebase
    • Auth
    • Storage
    • Firestore DB
  • TypeScript

Web

  • React.js

App

  • React Native

3. 핵심 기능

이 앱은 스마트 미러에 날씨, 시간별로 어떤 메세지를 보여줄지, 어떤 미세먼지 측정소의 데이터를 보여줄지, 어떤 사진들을 보여줄지 선택하는 컨트롤러입니다.

3.1 Firebase Storage에 사진 및 동영상 CRUD

  • 유저는 앱에서 Storage에 사진 및 동영상을 업로드할 수 있습니다.
  • 유저가 선택한 미디어가 동영상일 경우 FFMPEG를 사용해 gif로 변환 후 Storage에 업로드합니다.
  • 업로드된 사진은 언제나 삭제할 수 있습니다.

3.2 Storage에서 선택한 사진(사진 및 gif) 스마트 미러에 보여주기

  • 유저는 앱에서 스마트 미러에 출력할 사진을 Storage에서 최대 4개까지 정할 수 있습니다.

3.3 주소별 미세먼지 측정소 조회 및 저장

3.4 날씨, 시간대별 출력 메세지 CRUD

  • 날씨, 시간대별로 스마트 미러에 출력할 메세지를 관리할 수 있습니다.

4. 핵심 트러블 슈팅

4.1 리팩토링 전 기능에 비해서 처참한 앱의 퍼포먼스 문제

  • 리팩토링 전 개인용으로 사용하고 있던 앱은 단순한 사진 CRUD 기능밖에 없음에도 불구하고 단순 스크롤에도 렉이 심한 퍼포먼스 문제가 존재했습니다.
  • 이를 해결하기 위해서 코드 스플리팅, memoization, Presenter Container Pattern등을 사용해 최적화를 진행했습니다.
  • 🌐 리팩토링 전 App.js
    • 코드 스플리팅 없이 앱의 모든 기능이 App.js에 존재합니다.
    • 이로 인해 App.js의 코드가 길어지고, 컴포넌트가 불필요하게 리렌더링 되는 문제가 발생합니다.
  • 🌐 리팩토링 후 App.tsx
    • 코드 스플리팅을 통해 컴포넌트를 분리했습니다.
    • 앱의 기능이 훨씬 더 다양해지고 복잡해졌음에도 불구하고 동일한 역할을 하는 컴포넌트에서 성능이 훨씬 더 좋아졌습니다.

4.2 React Native에서 FFMPEG 사용할때 에뮬레이터와 실제 기기의 파일 경로 차이

  • Storage에 비디오를 업로드한다면 용량이 너무 커서 앱의 퍼포먼스에 악영향을 미치고, 스마트 미러에 출력할 때도 너무 느려질 것 같다고 생각해 gif로 변환해서 업로드하기로 했습니다.
  • 에뮬레이터로 테스트할 때는 문제가 없었지만 실제 기기에서 테스트할 때는 gif가 변환되지 않고 Storage에 blob 형태로 업로드되는 문제가 발생했습니다.
  • 확인 결과 에뮬레이터와 실제 기기의 파일 경로가 다르기 때문에 발생하는 문제였습니다.
  • 🌐 코드 비교
    • RNFS.readDir로 가져온 파일 경로에서 동영상 변환때 지정해준 이름을 가진 파일을 찾아 그 경로를 사용해 파일을 업로드해 에뮬레이터, 실제 기기 모두에서 동일하게 동작하도록 했습니다.

4.3 React Native Firebase Auth의 onAuthStateChanged()가 예상대로 작동하지 않는 문제

  • onAuthStateChanged()가 반환하는 유저 정보가 이미 이전에 로그아웃한 유저의 정보인 경우가 발생했습니다.
  • 에뮬레이터, 실제 기기, 모두에서 동일한 문제가 발생하였고 앱과 Firebase 패키지 재설치, 캐시 초기화, 함수 위치 변경 등의 시도를 해봤지만 문제가 해결되지 않았습니다.
  • onAuthStateChanged() 함수를 사용하지 않고 Recoil과 Recoil Persist를 사용해 유저 정보를 관리하는 방법으로 문제를 해결했습니다.
  • 🌐 코드 비교
    • react-native-recoil-persist 패키지를 사용해 Recoil 상태를 AsyncStorage에 저장하고, 앱이 실행될 때 AsyncStorage에서 유저 정보를 불러와 이를 사용하여 로그인 여부를 판단하도록 했습니다.

5. 기타 트러블 슈팅

5.2 React Navigation과 TypeScript 연동

  • JS 프로젝트를 TS 프로젝트로 변환하면서 React Navigation에 필요한 타입들을 추가해야 했습니다.
  • 생각보다 많은 타입들이 필요했고 공식 문서와 Stack Overflow를 참고해서 타입들을 추가했습니다.

6. 동작 화면

6.1 Storage 업로드

_.mov

6.2 스마트 미러에 사진 보여주기

default.mov

6.3 미세먼지 측정소 변경

default.mov

6.4 메세지 추가

default.mov

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages