pubsub schedule cloud function 만들어서 자동으로 데이터 업데이트 시키기

Jung Hyun Kim·2021년 3월 26일
2

pubsub schedule 을 사용한 cloud function으로 firebase자동 업데이트 하기 💻

현재 회사에서는 firebase를 사용하여 데이터를 관리하고 있고, 각 무인카페 키오스크 별 판매량 및 인기메뉴를 보여주는 화면이 있는데, 해당 내용을 각각 키오스크마다 정해진 시간에 업데이트 해주기 위해 pubsub function을 만들어서 자동 업데이트가 되게끔 만들었다.

현재 각 기기마다 아래와 같은 데이터가 매주 일요일 저녁 11시 59분에 업데이트 되게끔 만들었다.

이 함수를 만들면서 알게된 내용을 정리해보고자 한다. (dev 버전이라 나 99번 주문 실화소니?ㅎㅎㅎ)

  1. schedule은 pubsub emulator로 작동시킬수 없다. (아직 기능 지원x)

    • 현재 우리프로젝트는 testCafe를 사용해서 e2e test를 하고있는데, 특정 구매 후 스티커 발급이나 쿠폰 발급이 잘 되는지를 확인하기 위해 emulator 상에서 e2e test를 진행한다. schedule 함수를 만들면서 당연히 pubsub도 emulator지원을 하기때문에 pubsub emulator로 검사해보려 했는데.. 현재기준 pubsub은 지원하지만 schedule함수는 지원하지 않고 있어서 emulator상에서는 제대로 작동하는지 알 수가 없다. 즉.. 실제 firestore를 복사해서 검사하거나, Test 콜렉션에서 검사해보는 수밖에..없었다 ㅠㅠ

  1. cron time을 써서 schedule함수에 입력할때는 cron time 자체가 기준이 UTC여도, timeZone(기준시간대 in string)으로 명시를 해주어야 한다.(아닐수도 있으나, 적어도 해당 함수에서는 계속 작동을 안하다가 timeZone을 명시해주니 정상적으로 작동하였다)

	exports.scheduledFunctionCrontab = functions.pubsub.schedule('5 11 * * *')
 	 .timeZone('America/New_York') // Users can choose timezone - default is America/Los_Angeles
  	.onRun((context) => {
  	console.log('This will be run every day at 11:05 AM Eastern!');
  	return null;
	});

  1. iterable한 array는 Promise.all(array) 을 통해 작동시킨다.

    • 업데이트 해주고 싶은 키오스크(vending machine을 줄여 vm 으로 명명한다)를 array에 담고, 그 array를 map함수로 iterate하면서 원하는 데이터를 각각 넣어주는데, snapshot으로 가져올때부터 비동기를 동기처럼 작동시키려고 await를 써서 가져왔기때문에, array자체에 map함수에돌린다고 원하는 대로 실행되지 않고 map돌리는 array를 Promise.all(array) 처리를 통해 실행해주면 원하는대로 작동 시킬 수 있다. 공식 문서 설명

실제 코드(중간 생략 있음)

exports.updateVmHistory = functions.pubsub

// 한국 시간 기준 일요일 밤 11시 59분 이다. 
 .schedule('59 14 * * 0')
 .timeZone('UTC')
 .onRun(async (context) => {
   const snapShot = await DB.collection(VM_PATH).get();
 
// 적용시킬 키오스크만 배열에 담기위해 아래와 같이 filter 해 주었다

   const allVms = snapShot.docs
     .map((doc) => doc.data().id)
     .filter(
       (vm) => vm === 'BETA0007' || vm === 'BETA0010' || vm === 'BETA0008' || vm === 'BETA0012' || vm === 'TEST0000',
     );
 
..중략

   const mappingVm = allVms.map(async (vm) => {
     
 ...중략

// 각 vm에 firebase를 업데이트 해주고       
     await DB.doc(`${VM_PATH}/${vm}`).update({
       summary: {
         history: {
           startDate: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
           endDate: new Date(),
           weeklySales: weeklySalesResult,
           weeklyUsersRanking: topThreeUsers,
         },
       },
     });
   });
 
 // 위에 선언한 mappingvm을 promise.all 처리 하면 된다. 
   await Promise.all(mappingVm);
   return null;
 });
profile
코린이 프론트엔드 개발자💻💛🤙🏼

1개의 댓글

comment-user-thumbnail
2022년 10월 26일

emulator에서 스케쥴 동작을 아무리 걸어도 안되서 헤매고 있었는데.. 지원을 안하던거였군요 ...ㅠㅠ

답글 달기