Categories

🛠️

클라이밍 세팅 일정 알리미 - Flutter Web View, FCM

🗂️ wallert
목차

Wallert 프로젝트에 WebView를 이용한 기능을 추가하고, FCM 기능을 수정하는 과정을 다룹니다.

일정 데이터 제공 방향에 대해

이전 글

⚠️ 클라이밍 세팅 일정 알리미 - Wallert admin 페이지와 데이터 처리

에서의 작업으로, 어드민 페이지를 통해 실제 일정 데이터를 관리할 수 있게 되었습니다.

이제 해당 데이터를 사용자들이 제공 받을 수 있도록 해야하는데요. 아래 세가지 기능으로 제공할 예정입니다.

  1. 알림 구독을 통해 n일 전에 알림을 받는다.
  2. 일정이 적힌 달력을 앱 상에서 확인한다.
  3. 다녀간 암장과 날짜를 입력 한 뒤, 언제 가면 뉴 셋인지 계산된 날짜를 확인한다.

1. 알림 구독을 통해 n일 전에 알림을 받는다.

현재 구현되어있는 FCM 기능은 인스타그램 게시글 이미지 처리 서버를 통해 알림을 보내고 있는데요. 알림을 보내는 스크립트가 참조하는 DB를 어드민에서 관리하는 새 DB로 바꾸고 로직을 수정하면 되기 때문에 많이 어렵지않습니다.

2. 일정이 적힌 달력을 앱 상에서 확인한다.

Flutter 숙련도가 떨어지는 제 입장에서는 이 부분이 제일 문제입니다. 달력 기능이 기존 기능보다 복잡하기도 해서, AI에 기술적으로 의존하고있는 현 상태에서 네이티브로 개발하기에는 무리라고 판단했습니다.

그래서 개발 시간을 단축시키고, 최대한 개발자인 제가 제어 가능하도록 구현하기 위해 달력 부분은 웹 뷰로 구현하기로 했습니다. 사소한 기능 또는 오류를 수정하는데에도 속도면에서 꽤 이점이 있을거라 생각합니다.

3. 다녀간 암장과 날짜를 입력 한 뒤, 언제 가면 뉴 셋인지 계산된 날짜를 확인한다.

이 기능 역시 웹 뷰로 구현할 예정입니다.

작업 우선순위는 2 - 1 - 3 순입니다.


Flutter Web View 구현

웹뷰는 webview_flutter 패키지로 구현합니다.

dependencies:
  webview_flutter: ^4.2.1

dart 언어는 아직 거의 ai를 통해 개발하기 때문에 따로 설명하지는 않겠습니다.😂

PC/앱 캡쳐 이미지 어드민 달력
PC/앱 캡쳐 이미지 앱에서 표기되는 달력

현재 어드민 페이지에 추가되어있는 달력을 그대로 노출시킵니다. 근데 어드민은 제가 데이터 추가하는 화면이라, 추후에 웹뷰 출력용 페이지를 따로 만들어서 그 화면으로 연결할 생각입니다.


FCM 로직 변경

FCM 쪽 로직을 변경하기 전에 데이터 추가가 필요합니다.😑 데이터 수집을 셀프로 변경했으니..
다행히 더클라임 브랜드의 3월 일정은 앱에서 쉽게 확인이 가능하니 모두 추가하도록 하겠습니다.

더클라임 3월 일정 등록 완료 모든 더클라임 암장의 3월 세팅 일정 등록

이제 FCM을 수정해야합니다. FCM은 유저가 토픽구독하고, 알림을 보내는 쪽(서버)에서는 해당 토픽을 구독한 유저들에게 특정 알림을 보낼 수 있도록 되어있습니다.

다행히 이미 구독기능을 만들었고, 알림으로 보낼 내용만 변경하면 되기 때문에 앱이 아닌 알림을 보내는 서버쪽만 수정하면 되죠.

FCM 서버 코드 수정

/**
 * 스케줄 테이블에서 하루 뒤 일정 가져와서 알림 전송
 */
async function checkAndNotifySchedule() {
  try {
    const [schedules] = await db.promise().query(`
            SELECT id, brand_name, name_kr, type, wall_name, date
            FROM schedules
            WHERE date = CURDATE() + INTERVAL 1 DAY;
        `);

    if (schedules.length === 0) {
      console.log("발송할 일정이 없습니다.");
      return;
    }

    for (const schedule of schedules) {
      const { brand_name, name_kr, type, wall_name, date } = schedule;
      const topic = brand_name.replace(/ /g, "_").toLowerCase();
      const title = `${name_kr} 공지`;
      const eventType = type === "SETTING" ? "세팅 예정" : "탈거 예정";
      const formattedDate = new Date(date).getDate(); // 날짜 추출
      const body = `내일(${formattedDate}일)은 ${name_kr} ${wall_name}${eventType}일 입니다.`;
      const image = `이미지 추가 필요`;

      console.log("알림 발송:", { topic, title, body });
      await sendPushNotificationToTopic(topic, title, body, image);
    }
  } catch (error) {
    console.error("스케줄 알림 확인 중 오류 발생:", error);
  }
}

// 매일 10시(KST 19시) 알림 발송
schedule.scheduleJob("0 10 * * *", () => {
  checkAndNotifySchedule().catch((error) => {
    console.error("스케줄 알림 오류:", error);
  });
});

스케쥴을 통해 매일 오후 7시 schedules 테이블에서 조회 시간 기준 +1일(내일)에 있는 일정을 조회하여 해당 암장 토픽으로 알림을 보냅니다. 이제 해당 암장을 구독한 유저는 세팅 하루 전 날에 알림을 받을 수 있습니다.

모바일에서 알림을 받은 캡쳐 사진 앱에서 받은 알림

벽 이름이 유니크한 암장도 있지만 알림의 3, 4 처럼 숫자로 되어있어서 직관적으로 알아보기 힘들 수 있기 때문에 사진 영역에는 각 벽의 모델링 사진을 추가할 예정입니다.

이제 아래 두가지는 완료되었습니다.

  1. 알림 구독을 통해 n일 전에 알림을 받는다.
  2. 일정이 적힌 달력을 앱 상에서 확인한다.

이제 원래대로 라면 3번 기능이 남았는데요. 여기서 조금 고민이 생겼습니다.


🤔 기능에 대한 고민

다녀간 암장과 날짜를 입력 한 뒤, 언제 가면 뉴 셋인지 계산된 날짜를 확인한다.

우선 비슷한 기능을 어드민에 테스트로 만들어놨습니다. 모든 일정을 불러와서 가장 가까운 일정이 어떤 일정인지 순서대로 나열하는 기능이죠.

그런데 3번 기능에 대해 생각해보니 유저가 이 기능을 쓸까 싶습니다. 개인적인 생각으로는, 이 앱은 설명하긴 애매하지만 어쨋든 비공식인 서드파티 앱이고 그중에서도 간단하게 편의를 위해 알림 기능을 제공하는 앱 인데.. 사용자들이 굳이 들어와서 기능을 사용하도록 해야할까? 하는 생각입니다. 처음 설계에서 벗어난것 같은 느낌이죠.

벽 이미지를 추가하기 전까진 우선 이상태로 멈출 예정입니다.