- Today
- Total
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- dbeaver
- 트러블슈팅
- TIL
- 환경세팅
- Oracle
- spring boot
- Hostinger
- PLSQL
- iframe
- 이클립스
- 의존성주입
- javascript
- mysqli
- 백엔드
- url파라미터
- 오라클
- 오류해결
- 엘리멘터
- 오블완
- 문제해결
- 클론코딩
- 티스토리챌린지
- PROCEDURE
- 프로시저
- 워스프레스
- MariaDB
- sql
- 워드프레스
- PDO
- 쿼리개선
개발 공부중
[사이드 프로젝트 회고 #2] 푸시 기능을 앱 대신 FCM(Firebase Cloud Messaging)으로 해결하기 본문
[사이드 프로젝트 회고 #2] 푸시 기능을 앱 대신 FCM(Firebase Cloud Messaging)으로 해결하기
개발자 leelee 2026. 7. 5. 16:15
1편에서 닷홈빌더의 한계 때문에 PHP로 새로 사이트를 만들기로 했다. 사이트를 다 완성하고 알림 기능을 추가하기 전에 그다음 고민으로 "이걸 어떤 방식으로 구현할까" 생각해봤다.
알림이 필요하면, 앱을 만들어야 하는 거 아닌가?
새 글 알림, 댓글 알림 기능이 필요하다는 결론을 내리고 나서, 가장 먼저 떠오른 방법은 사실 "앱으로 만들기"였다. 푸시 알림이라는 게 원래 앱에서 흔히 쓰는 기능이라, "그냥 앱 하나 만들면 되지 않을까"라는 생각이 자연스럽게 들었다.
근데 생각해볼수록 앱으로 가는 건 이 프로젝트의 규모와 전혀 맞지 않았다.
- 안드로이드/iOS 각각 개발해야 하거나, 최소한 크로스플랫폼 프레임워크를 새로 익혀야 한다
- 앱스토어/플레이스토어 등록 절차와 심사를 거쳐야 한다
- 이미 PHP로 만든 웹사이트가 있는데, 그걸 앱으로 다시 만드는 건 중복 작업이다
이용자가 적은 익명 글쓰기 사이트 하나에 알림 기능을 붙이려고 앱까지 새로 만드는 건, 배보다 배꼽이 큰 선택이었다.
차라리 네이버 카페 기능을 쓰는게 나을 정도...
아이폰의 "홈 화면에 추가" 기능이 힌트가 됐다
찾아보니 아이폰의 홈 화면에 추가 기능으로 웹사이트를 어플처럼 이용할 수 있었다. 사파리에서 웹사이트를 열고 "홈 화면에 추가"를 누르면, 그 사이트가 마치 하나의 앱처럼 아이콘으로 홈 화면에 생긴다. 이 상태로 열면 브라우저 주소창도 사라지고, 진짜 앱을 켠 것 같은 느낌을 준다.
이렇게 홈 화면에 추가한 상태에서도, 푸시 알림을 받을 수 있을까?
FCM (Firebase Cloud Messaging)
이 질문에 대한 답을 찾다가 Firebase Cloud Messaging(FCM)을 알게 됐다. FCM은 원래 안드로이드/iOS 앱을 위한 푸시 서비스로 많이 알려져 있지만, 웹 푸시(Web Push) 도 지원한다. 그리고 확인해보니 이 웹 푸시가 홈 화면에 추가한 PWA(Progressive Web App) 상태에서도 정상적으로 동작한다는 걸 확인했다.
정리하면 이렇게 방향이 잡혔다.
- 앱을 새로 만드는 대신, 기존 PHP 웹사이트를 그대로 유지한다
- 아이폰/안드로이드 사용자는 "홈 화면에 추가"로 앱처럼 쓰게 한다
- 알림은 FCM 웹 푸시로 처리해서, PC 브라우저와 홈 화면에 추가된 모바일 상태 모두에서 받을 수 있게 한다
이 방향이면 앱스토어 심사도, 별도 앱 개발 비용도 없이 "새 글이 올라오면 알려주는 앱 같은 사이트"를 만들 수 있었다.


푸시 알림 구조
방향을 정하고 나서 실제로 붙인 흐름을 정리하면 이렇다.
사용자
│
▼
'새 글 알림 받기' 버튼 클릭
│
▼
Notification API 권한 요청
│
▼
FCM getToken()
│
▼
fcm_tokens 테이블 저장
│
▼
게시글 작성
│
▼
send_new_post_notification()
│
▼
send_notification()
│
├── notifications 테이블 저장
│
└── fcm_tokens 조회
│
▼
사용자의 모든 토큰 조회
│
▼
fcm_send_to_token()
│
▼
Firebase HTTP v1 API
│
▼
PC / 모바일 푸시
이걸 크게 세 단계로 나눠보면 이렇다.
1. 프론트에서 알림 권한을 요청하고 토큰을 발급받는다.
async function requestNotificationPermission() {
const permission = await Notification.requestPermission();
if (permission === "granted") {
const token = await messaging.getToken({
vapidKey: "발급받은_VAPID_KEY"
});
// 발급받은 토큰을 서버로 전송해서 저장
fetch("save_token.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token })
});
}
}
2. 게시글이 등록되면 구독자를 먼저 조회한다. 게시글이 등록됐다고 모든 사용자에게 알림을 보내는 건 아니었다. 게시판을 구독한 사용자만 조회하도록 구현했다. 실제로는 send_new_post_notification()에서 먼저 구독자를 가져온다.
$stmt = $pdo->prepare("
SELECT user_id
FROM board_subscriptions
WHERE board_type = :type
AND user_id != :writer_id
");
$stmt->execute([
':type' => $board_type,
':writer_id' => $writer_id
]);
$subscribers = $stmt->fetchAll(PDO::FETCH_COLUMN);
작성자는 제외하고, 구독한 회원에게만 알림을 보내도록 했다.
3. send_notification() 하나에서 모든 알림을 처리하도록 만들었다.
처음에는 게시글 알림, 댓글 알림, 답글 알림마다 각각 FCM을 호출하려고 했다. 그런데 같은 코드가 계속 반복됐다. 그래서 알림 저장 + 푸시 발송을 모두 처리하는 send_notification() 함수를 하나 만들었다. 이 함수는 다음 세 가지를 모두 담당한다.
- notifications 테이블 저장
- 사용자의 FCM 토큰 조회
- 모든 토큰으로 푸시 발송
4. 먼저 사이트 알림을 저장한다.
푸시만 보내면 사용자가 알림을 놓쳤을 때 확인할 방법이 없다. 그래서 가장 먼저 notifications 테이블에 저장하도록 만들었다.
INSERT INTO notifications
(
user_id,
type,
target_id,
message,
url
)
이렇게 저장해두면
- 사이트 안에서도 알림 목록을 볼 수 있고
- 읽음 처리도 가능하며
- 삭제도 할 수 있다.
5. 저장된 모든 토큰으로 푸시를 보낸다. 그다음이 FCM이다.
$stmt = $pdo->prepare("
SELECT token
FROM fcm_tokens
WHERE user_id = :uid
");
$stmt->execute([
':uid' => $to_user_id
]);
$tokens = $stmt->fetchAll(PDO::FETCH_COLUMN);
foreach ($tokens as $token) {
fcm_send_to_token(
$token,
$title,
$message,
$url
);
}
여기서 fetchAll()을 쓴 이유는, 한 사용자가 PC와 모바일 두 곳 모두 로그인한 경우 두 기기로 모두 알림을 보내기 위해서였다.
6. 실제 유저가 푸시 알람을 설정하는 방법
상단 🔔 클릭 후 푸시 켜기 버튼을 누르면
댓글, 답글, 새 글 알림(+개별페이지에서 클릭 필수)을 받을 수 있습니다.
아이폰은 Safari에서 사이트 접속 후
공유 버튼 → 홈 화면에 추가 → 홈 아이콘으로 실행해야 푸시 알림이 작동합니다.
갤럭시는 Chrome 브라우저에서
푸시 켜기 버튼을 누르면 바로 사용할 수 있습니다.
7. 그런데 이 구조 때문에 버그도 발생했다.
이 방식은 여러 기기를 쓰는 사용자에게는 편리했지만, 개발하면서 테스트를 반복하다 보니 문제가 생겼다. 처음엔 같은 계정으로 PC에서 '새 글 알림 받기' 버튼을 눌러 토큰을 저장했다. 이후 모바일에서도 같은 계정으로 알림을 허용했다. 그런데 개발 과정에서 기존 PC 토큰이 정리되지 않은 채 fcm_tokens 테이블에 그대로 남아 있었다.
당장은 두 기기 모두에 알림이 잘 가는 것처럼 보였지만, 초기화가 제대로 안 된 토큰들이 결국 "알림이 중복으로 오는 버그"로 나타났다.
이 선택이 이후 구현에 준 영향
이 결정은 이후 알림 기능을 구현하는 방식 전체에 영향을 줬다. 앱 하나만 있었다면 "이 사용자에게 보낸다"는 개념으로 끝났을 텐데, "웹사이트 + PWA + FCM" 조합에서는 한 사용자가 여러 토큰(기기)을 가질 수 있다는 걸 구조적으로 감당해야 했다. 바로 위에서 언급한 PC 토큰이 정리되지 않고 남아있던 문제도 결국 이 구조 때문에 생긴 일이었다.
돌아보며
앱을 만들지 않기로 한 선택으로 배포·심사·업데이트 같은 앱 특유의 운영 부담 없이 빠르게 기능을 붙이고 고칠 수 있었다.
개인이 혼자 운영하는 사이드 프로젝트에는 이 쪽이 훨씬 현실적인 선택이었다고 생각한다.