[JavaScript] Firebase Cloud Functions 연동(2) - 지정된 시간마다 호출되는 함수

구현 목표

평일 오후 5시~5시 50분에 10분 간격으로 자동 실행되는 함수를 만들었다.

함수가 실행되면 조건 충족 여부에 따라 DB에 데이터를 추가한다.

 

onSchedule 예약 함수 작성

지정된 시간에 함수를 실행하도록 예약하려면 `firebase-functions/v2/scheduler`에서 제공하는

`onSchedule` 핸들러를 사용하여 지정한 시간마다 함수 로직을 호출한다.

 

이를 위해서는 프로젝트에 `Cloud Scheduler API`가 사용 설정되어 있어야 하는데,

대부분의 Firebase 프로젝트에서는 이미 사용 설정이 되어 있을 것이다.

사용 설정 여부는 Google Cloud 콘솔에서 확인할 수 있다.

 

const { logger, setGlobalOptions } = require("firebase-functions/v2");
const { onSchedule } = require("firebase-functions/v2/scheduler");
const { initializeApp } = require("firebase-admin/app");
const { getFirestore } = require("firebase-admin/firestore");

const fetch = require("node-fetch");
const cheerio = require("cheerio");

initializeApp();
setGlobalOptions({ region: "asia-northeast3" }); // 함수 리전 설정

exports.checkTodayPointLink = onSchedule(
  {
    schedule: "0,10,20,30,40,50 17 * * 1-5", // 평일 17:00~17:50 10분 간격으로 실행
    timeZone: "Asia/Seoul",
  },
  async (event) => {
    const dateStr = getTodayString();
    try {
      // 1. 공휴일 확인
      const isHolidayResult = await isHoliday(dateStr);
      if (isHolidayResult) {
        logger.log("❌ 공휴일이므로 조기 종료합니다.");
        return;
      }

      // 2. 오늘 날짜로 이미 저장된 문서가 있는지 확인
      const isAlreadySavedResult = await isAlreadySaved(dateStr);
      if (isAlreadySavedResult) {
        logger.log(
          "❌ 이미 해당 날짜로 저장된 문서가 있으므로 함수를 종료합니다."
        );
        return;
      }

      // 3. 이벤트 링크 찾기
      const eventLink = await getEventLink();

      if (eventLink) {
        logger.log("✅ 이벤트 링크를 찾았습니다", {
          link: eventLink,
        });

        // 4. DB 저장
        const data = {
          link: eventLink,
        };

        await getFirestore().collection("pointDays").doc(dateStr).set(data);
        logger.log("✅ 문서가 성공적으로 생성되었습니다", {
          documentId: dateStr,
          collection: "pointDays",
          data: {
            link: data.link,
          },
        });
      } else {
        logger.log("❌ 이벤트 링크를 찾지 못했습니다");
      }
    } catch (error) {
      logger.error("❌ checkTodayPointLink 함수 실행 중 오류 발생", {
        date: dateStr,
        error: error.message,
        stack: error.stack,
        functionName: "checkTodayPointLink",
      });
    }
  }
);

함수의 작동 흐름은 다음과 같다.

  1. 이 함수는 평일 17:00~17:50까지 10분 간격으로 실행된다.
  2. 이벤트가 공휴일이 아닌 평일에만 진행되기 때문에 오늘이 공휴일이라면 함수를 종료한다.
  3. 이벤트 링크가 게시되는 시간이 일정하지 않기 때문에 5시부터 10분 간격으로 설정했다. 만약에 앞선 함수 실행에서 이벤트 링크를 찾아서 이미 DB에 저장했다면 반복 실행하지 않고 함수를 종료한다.
  4. 이벤트 링크를 찾았다면 DB에 새로운 문서를 추가한다.

 

함수 실행 시간 설정

schedule: "0,10,20,30,40,50 17 * * 1-5"

함수 실행 시간은 UNIX cron format을 이용해 작성했다.

Desired task schedule schedule value
2:10 PM every Monday 10 14 * * 1
Every day at midnight 0 0 * * *
Every weekday at midnight 0 0 * * 1-5
Midnight on 1st and 15th day of the month 0 0 1,15 * *
6.32 PM on the 17th, 21st and 29th of November plus each Monday and Wednesday in November each year 32 18 17,21,29 11 mon,wed

 

함수 테스트

cd functions
firebase functions:shell
함수_이름()

다음과 같은 명령어로 함수를 실행한다.

 

예약된 시간에 자동으로 실행되는 것을 테스트할 수는 없지만 

함수가 정상적으로 작동하는지를 직접 실행해 볼 수 있다.

 

함수 배포

firebase deploy --only functions:함수_이름

다음 명령어를 통해 함수를 배포한다.

 

배포가 정상적으로 완료되면 Firebase Console 페이지에서 확인할 수 있다.

 

로그 조회

상단의 코드에서 `loggger.log()` 또는 `logger.error()`를 통해 로그를 출력하고 있다.

이 로그들은 다음 페이지에서 조회할 수 있다.

 

`구글 클라우드 콘솔 > Cloud Run < 서비스` 페이지에서 함수별로 로그를 확인할 수도 있고

https://console.cloud.google.com/run

 

`구글 클라우드 콘솔 > 로깅 > 로그 탐색기` 페이지에서 전체 로그를 한 번에 확인할 수도 있다.

https://console.cloud.google.com/logs/query

 

또한 `Cloud Scheduler` 페이지에서 스케줄 함수 세부 설정을 확인하거나 수정할 수도 있다.

https://console.cloud.google.com/cloudscheduler

 

Firebase Cloud Functions 연동 시리즈

 

참고 문서