From f2e7c035077d15152e3803fa41e20c39b61a945a Mon Sep 17 00:00:00 2001 From: chpark Date: Sat, 30 May 2026 22:09:12 +0900 Subject: [PATCH] =?UTF-8?q?fix(push-optin):=20=EC=82=BC=EC=84=B1=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=EB=84=B7=20=EC=A7=80=EC=9B=90=20+=20ArrayBuf?= =?UTF-8?q?fer=20applicationServerKey?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 원인 1: applicationServerKey 타입 호환성 - Samsung Internet 은 Uint8Array 거부, ArrayBuffer 만 허용 (Chrome 은 둘 다 OK) - urlBase64ToUint8Array(publicKey).buffer 로 ArrayBuffer 명시 전달 원인 2: 사용자 환경별 안내 부재 - userAgent 의 SamsungBrowser 감지하여 isSamsungBrowser 분기 추가 - denied 모달에 삼성 인터넷 전용 가이드: 메뉴(≡) → 설정 → 사이트 권한 → 알림 → momotogether.com 허용 - 카드 하단 환경 진단에 '삼성 인터넷' / '안드로이드(Chrome)' 구분 표시 원인 3: 푸시 구독 실패 메시지 모호 - pushManager.subscribe 에러 메시지에 사이트 권한 차단 가능성 힌트 추가 Co-Authored-By: Claude Opus 4.7 --- src/components/push-optin.tsx | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/components/push-optin.tsx b/src/components/push-optin.tsx index 3666799..942a2ec 100644 --- a/src/components/push-optin.tsx +++ b/src/components/push-optin.tsx @@ -92,12 +92,21 @@ export function PushOptIn({ variant = "compact" }: PushOptInProps) { const { publicKey } = await res.json(); if (!publicKey) throw new Error("서버가 VAPID 공개키를 반환하지 않았습니다."); try { + // Samsung Internet 은 ArrayBuffer 만 받음 (Uint8Array 그대로 넣으면 거부). + // Chrome 도 ArrayBuffer 받으므로 .buffer 로 통일. + const keyBuf = urlBase64ToUint8Array(publicKey).buffer as ArrayBuffer; sub = await reg.pushManager.subscribe({ userVisibleOnly: true, - applicationServerKey: urlBase64ToUint8Array(publicKey) as BufferSource, + applicationServerKey: keyBuf, }); } catch (e) { - throw new Error(`푸시 구독 실패: ${(e as Error).message ?? e}`); + const msg = (e as Error).message ?? String(e); + // Samsung Internet 특유 메시지 변환 + let hint = ""; + if (/abort|denied|NotAllowed/i.test(msg)) { + hint = " (브라우저 설정에서 알림 차단됨 가능성 — 사이트 권한 확인)"; + } + throw new Error(`푸시 구독 실패: ${msg}${hint}`); } } @@ -294,10 +303,11 @@ export function PushOptIn({ variant = "compact" }: PushOptInProps) { } // === card 변형 (회원정보 페이지) === - // denied 환경 감지 — TWA 앱은 안드로이드 OS 설정, 브라우저는 사이트 설정에서 풀어야 + // denied 환경 감지 — TWA / Samsung Internet / Chrome / iOS 별 안내 분기 const ua = typeof navigator !== "undefined" ? navigator.userAgent : ""; const isAndroid = /Android/i.test(ua); const isiOS = /iPhone|iPad|iPod/i.test(ua); + const isSamsungBrowser = /SamsungBrowser/i.test(ua); const isTWA = isAndroid && (/wv|; ?Trusted Web Activity/i.test(ua) || (typeof document !== "undefined" && (document.referrer ?? "").startsWith("android-app://"))); return ( @@ -330,7 +340,16 @@ export function PushOptIn({ variant = "compact" }: PushOptInProps) {
알림 권한이 차단된 상태입니다 — 직접 풀어주세요
- {isTWA || isAndroid ? ( + {isSamsungBrowser ? ( +
    +
  1. 삼성 인터넷 앱 → 우측 하단 ≡ (메뉴)설정
  2. +
  3. 사이트 및 다운로드사이트 권한알림
  4. +
  5. 차단됨 목록에서 momotogether.com 찾기 → 삭제 또는 허용
  6. +
  7. 또는 위쪽 모든 사이트 보기 → momotogether.com → 알림 → 허용
  8. +
  9. 모모유통 페이지로 돌아와 새로고침 후 토글 다시
  10. +
  11. 그래도 안 되면: 삼성 인터넷 앱 설정 → 개인정보 → 인터넷 데이터 삭제 → 쿠키와 사이트 데이터 ✓ → 삭제
  12. +
+ ) : isTWA || isAndroid ? (
  1. 안드로이드 설정 앱을 엽니다
  2. 앱 → 모모유통 (또는 브라우저 이름) → 알림
  3. @@ -362,7 +381,7 @@ export function PushOptIn({ variant = "compact" }: PushOptInProps) { 진단 · 권한: {typeof Notification !== "undefined" ? Notification.permission : "?"} {" · "}보안: {httpsOK ? "OK" : "NO"} {" · "}SW: {"serviceWorker" in (typeof navigator !== "undefined" ? navigator : ({} as Navigator)) ? "지원" : "미지원"} - {" · "}환경: {isTWA ? "TWA앱" : isAndroid ? "안드로이드" : isiOS ? "iOS" : "데스크탑/기타"} + {" · "}환경: {isTWA ? "TWA앱" : isSamsungBrowser ? "삼성 인터넷" : isAndroid ? "안드로이드(Chrome)" : isiOS ? "iOS" : "데스크탑/기타"} );