iOS PWA에서 SW가 앱을 제어하지 않아 푸시 알림 구독이 조용히 실패하는 문제

안녕하세요 :waving_hand:

iOS PWA에서 푸시 알림을 설정할 때 이상한 동작(아마도 버그…)을 경험했습니다. UI는 푸시 알림 구독이 설정된 것처럼 보이지만, 백그라운드에서는 아무 일도 일어나지 않았고 사용자는 푸시 알림을 절대 받지 못합니다.

(요약: 해결 방법을 알고 있으며 PR을 제공할 수 있습니다)

재현 방법 :footprints:

이 문제는 iOS에서 PWA를 설치한 직후 푸시 알림을 활성화하는 것과 관련이 있습니다.

  1. iOS 모바일 Safari에서 Discourse 인스턴스를 엽니다.
  2. 공유 메뉴를 열고 "홈 화면에 추가"를 선택합니다.
  3. 홈 화면의 새 PWA를 엽니다.
  4. 푸시 알림을 활성화할지 묻는 배너가 표시됩니다.
  5. “알림 활성화” 링크를 클릭합니다.
    1. "xyz"가 사용자에게 알림을 보내려고 합니다라는 시스템 다이얼로그가 표시됩니다 - 허용을 선택합니다.
  6. 알림 설정으로 이동하면 실시간 알림활성화되지 않은 것을 볼 수 있습니다.
    1. 서버를 확인해도 해당 사용자의 새 PushSubscription 레코드를 찾을 수 없습니다.

예상 동작 :books:

5단계 이후에는 알림이 활성화되었음을 알리는 푸시 알림을 이미 받아야 합니다. 데이터베이스에는 현재 사용자의 새 PushSubscription 레코드가 생성되어야 하며, PWA에서 실시간 알림을 받는 설정이 활성화되어야 합니다.

문제 :bug:

방금 새로 시작된 PWA에서는 서비스 워커가 설치되고 활성화되었지만, 아직 페이지를 제어하지 않습니다. 이로 인해 lib/push-notifications.jsisPushNotificationsSupported() 체크는 여전히 false를 반환합니다. 그 이유는 navigation.serviceworker.controllernull을 반환하기 때문입니다. 다음은 중요한 두 줄입니다:

navigator.serviceWorker.controller &&
navigator.serviceWorker.controller.state === "activated"

이로 인해 UI는 사용자에게 설정이 정상적인 것처럼 보이게 하지만, 사용자는 푸시 알림을 절대 받을 수 없습니다.

첫 번째 로드 시 PWA는 제어되지 않은 상태이며, 사용자가 권한을 부여했음에도 subscribe() 호출이 결코 이루어지지 않습니다… :bug:

사용자가 방법을 안다면 스스로 문제를 해결할 수 있습니다:

  1. PWA를 완전히 닫습니다 (스와이프하여 제거…)
  2. PWA를 다시 엽니다
  3. 알림 설정으로 이동합니다
  4. 실시간 알림을 다시 활성화합니다
  5. -> 이번에는 새 PushSubscription 레코드가 생성되고 알림이 설정됩니다.

잠재적 수정안 :adhesive_bandage:

저는 설치/활성화 시 skipWaiting()clients.claim()을 호출하는 또 다른 서비스 워커를 등록하여 이 문제를 우회했습니다. 이렇게 하면 PWA의 제어를 즉시 넘겨받아 구독이 진행되고 각각의 PushSubscription 레코드가 생성됩니다.

저는 Discourse 코어 포크에 손을 대지 않고도 사용자의 상황을 수정할 수 있도록 이 내용을 "핫픽스"로 내 커스텀 플러그인 중 하나에 포함하여 배포했습니다…

변경 사항은 두 가지뿐입니다:

# plugin.rb
register_service_worker "push-notification-setup.js"
// assets/push-notification-setup.js
self.addEventListener("install", function () {
  self.skipWaiting();
});
		
		
self.addEventListener("activate", function (event) {	
  event.waitUntil(self.clients.claim());
});

하지만 이 수정은 Discourse 코어에 포함되어야 한다고 생각합니다. 제가 이렇게 하면 플러그인이 PWA에 대해 불필요한 제어를 하게 됩니다. 구독이 실제로 작동하도록 Discourse 코어의 체크를 조정하는 PR을 제공할 수 있습니다. 여기에서 자세히 말씀드리겠지만, 주제에 대한 의견을 미리 말씀해 주셔도 좋습니다.

5개의 좋아요

Discourse 코어 수정 사항이 포함된 PR입니다 → FIX: Allow push notification subscriptions on first launch of iOS PWA - Pull Request #39885 - discourse/discourse - GitHub

이 PR은 여기에서 설명된 문제를 수정하며, 구독이 조용히 실패하여 서버에 도달하지 않는 문제를 해결합니다. 하지만 완전히 안전하려면, 앱이 서비스 워커에 의해 제어되지 않는 한(즉, 사용자가 앱을 재시작하지 않는 한) 수신된 첫 번째 푸시 알림은 앱 내에서 라우팅할 수 없으므로, 이 부분이 여전히 빠져 있습니다.

이 부분은 제 PR에 추가로 포함할 수도 있습니다. 하지만 이 수정 방식이 원하는 것인지 100% 확신은 없습니다.

4개의 좋아요

메인 서비스 워커에 해당 내용을 추가하는 PR을 보내주실 수 있을까요? 그러면 이 문제가 해결되나요?

그렇게 하는 데 문제가 있나요?

2개의 좋아요

네. 어떻게 동작하는지 확인해 보고, PR을 업데이트한 후 준비되면 알려드릴게요.

my PR를 업데이트하여 서비스 워커가 즉시 PWA를 제어하도록 보장했습니다.

여러 배포 환경에서 몇 가지 더 테스트해야 할 것 같습니다. 하지만 먼저 :eyes: 해 주실 의향이 있으신가요?

1개의 좋아요