Project : memon

zenibako.lee
8 min readDec 12, 2019

--

19.11.11 ~ 19.12.7 4W

이 글은 3명이 4주간 진행한
‘memon’어플리케이션 제작기입니다.

본인은 이번 프로젝트에서 팀장을 맡았고,
Front-end 프로그래밍을 하였습니다.

구글플레이스토어 주소

서비스 설명

더치페이 기록 & 입금 요청을 간단하게.

STACK(FE)

React Native , Expo , Native-Base,
Firebase, expo-google-sign-in, Typescript

Google OAuth2.0 Login 구현

이번 프로젝트에서는 기존에 사용하던 자체 회원정보가 아니라,
OAuth2.0 기능을 이용한 로그인을 구현해보고 싶었습니다.
그 이유는 제가 필요한 정보 (유저의 이메일주소/토큰/이름)을 유저가 직접 입력하지 않아도, 동의 클릭으로 제공받을 수 있고,
보안도 직접 구현하는 것 보다 더 신용을 얻을 수 있다고 생각했습니다.

구현의 시작은 Expo 공식 document에서 제공하는
googleLogin 항목을 참고하여 진행하였습니다.

Expo-google-sign-in 모듈을 사용하였는데,

initAsync = async () => {await GoogleSignIn.initAsync({clientId: config.androidClientId});await this._syncUserWithStateAsync();};

이 때 , 모바일 환경에서 로그인 하기 위해서는 clientId 항목이 포함하여,

Async를 위한 준비를 하는 initAsync()메소드를 실제 loginAsync()이전에 실행해야 합니다.

이 clientId는

Firebase 콘솔에서 생성한 로컬 프로젝트와 동일한 패키지명을 가진
안드로이드 어플리케이션 프로젝트의 service.json을 다운로드받으면
확인할 수 있습니다.

해당 기능을 구현하면서 겪었던 고민과 그 해결은 아래의 글로 따로 작성하였습니다.

NewPayment.tsx
접근 방식에 따른 form 부분 활성화 구현

componentDidMount = async () => {  const { navigation } = this.props;  if (!navigation.state.params) {    console.log('새 글 등록, state.disabled:', this.state.disabled);  } else {    console.log('=========리스트에서 온거야 비활성화 해야해');const {fromListView,email,pricebookId,transCompleted} = navigation.state.params;.
.
.
}

state 초기값으로 기본 form render가 종료 된 후,

componentDidMount 시점에
this.props.navigation.state.params 의 존재 여부에 대한
boolean check를 합니다.

왜냐하면 메인 페이지에서, 새 결제 생성을 누른 경우에는 ‘작성모드’로 진입하도록, 즉

moveToNewPayment = () => {this.props.navigation.navigate('새거래');};

위와 같은 메소드를 onPress event callback으로 설정해 두었기 때문에, 따로 전달되는 params가 없기 때문입니다.

반면에 결제목록 페이지에서, 개별 결제를 클릭해서 NewPayment로 진입하는 경우에는, view모드로 진입하도록 구현했기 때문에

this.props.navigation.navigate(‘새거래’, {fromListView: true,email: this.state.email,pricebookId: payment.pricebookId,transCompleted: payment.transCompleted});

초기 정보를 구성하는 fetch 작업을 하기 위한 정보와, fromListView라는 key,value를 같이 갖고 오기 때문입니다.

transComplete가 true인 경우에는 이미 해당 결제는 완료 되었으므로, 수정이 불가능하도록, footer 버튼의 text를 ‘확인’으로 바꾸고 disable 처리합니다.

그러나 false인 경우에는 ‘수정’으로 화면 하단의 버튼을 설정합니다. 물론 버튼 클릭에 따라, input component들의 disable 속성이 true에서 false로 변경이 되고, 수정이 가능하도록 구현하였습니다.

프로젝트 팀장으로서의 후기

어플리케이션을 배포해보자! 하고 시작한 프로젝트였습니다.

그러나 어플리케이션 개발이 처음일 뿐 만 아니라, React Native를 처음 다루기 위해 시작했던 프로젝트인 만큼, 처음엔 아는것이 전무하여, 팀장이라는 무게감과 함께 큰 압박감을 받으며 초반을 보냈습니다.

훌륭한 팀원들과의 커뮤니케이션을 통해 으쌰으쌰 하며 이겨내며 느낀건,
처음 보는 기술,언어들은 앞으로도 계속 이어지겠지만,
결국 어떻게든 조금씩, 나아지며 구현에 성공을 할 것이고,
그 과정을 버티게 하는 힘은, 여러가지가 있겠지만
프로젝트 데드라인에 대한 압박감과, 서로 응원하는 팀원들간의 팀워크라고 생각합니다.

구현측면에서의 후기

아쉬웠던 점이 크게 두가지 존재한다.

1. Redux를 적용하지 않은것.

두가지 상황에서 redux를 사용하지 않은 것에 대한 후회가 있었다.

작성,보기,수정,결제완료처리 모드로 사용한 Component의 state

새결제 생성 페이지의 form은 작성,보기,수정,결제완료 처리에서 모두 동일하게 보여지기 때문에, 페이지를 분리하는 것이 소모적이라 생각하여,
state와 prop을 통해 단일 페이지를 재사용하는 방식으로 구현하였다.

그러다보니 상황에 따른 많은 분기가 필요했는데, 단일 페이지에서 구현하려다 보니 과도한 수의 state를 사용하고 있는 것으로 느껴졌다.

이 때 의문이 동시에 들기도 하였는데, 동일한 form을 사용한다고 단일 페이지를 고집할 필요가 있는지에 대한 의문이었다.

import firebase from 'firebase';import * as Contacts from 'expo-contacts';
const user = await firebase.auth().currentUser;const { data } = await Contacts.getContactsAsync({fields: [Contacts.PHONE_NUMBERS]});

위와 같이, 로그인 이후 현재 접속한 유저의 google 정보를 확인하기 위해, 그리고 디바이스의 주소록 정보를 얻기 위해
해당 정보가 필요한 모든 component, 혹은 method에서 계속 해당 정보를 불러오는 행위를 했어야 했다.

만약 redux의 container에 로그인 시에, 단 한번 저장을 해놓고, 해당 container의 정보만 호출하는 것으로 구현했다면, 중복된 동일 자료 fetch를 방지할 수 있었을 것으로 보인다.

2. 플레이스토어 업로드시 발생하는 google login 에러 문제

expo-google-sign-in

이라는 모듈을 사용하여, stand alone 배포시에도 작동하도록 google OAuth2.0 로그인 구현을 하였는데,

현재 .apk파일로 설치하면 정상 작동하는 것이, 플레이스토어에서 다운받으면 로그인이 제대로 동작하지 않고있다.

그렇다고 어플리케이션이 에러로 인해 종료되는 것도 아니고,

해당 모듈의 특성 상, expo-clinet위에서 실행이 불가능하다. 따라서 터미널에서의 디버깅이 불가능했다.

안드로이드 스튜디오 avd를 통해서 .apk를 테스트 하였을 때도 정상작동을 하였고, 플레이스토어에서 다운로드 받은 경우, 에러로그를 검출할 수 있을지 확인 후, 디버깅을 시도해보고자 하고 있다.

이후 디버깅에 성공,
현재 구글 플레이스토어에서 다운로드시 사용 가능하다.
아래는 해당 디버그를 스스로 기록해본 글이다.

--

--

zenibako.lee
zenibako.lee

Written by zenibako.lee

backend engineer, JS, Node, AWS

No responses yet