订阅后如何更新amp-web-push组件?解决订阅/拒绝通知后组件状态未同步问题
Fixing
amp-web-push Visibility State Issues Let's tackle your two amp-web-push problems head-on—both boil down to the component not getting accurate, timely updates about the user's subscription and permission state. Here's how to fix them:
Problem 1: Visibility doesn't update after successful subscription
Your service worker's onMessageReceivedSubscribe function was only sending a null reply instead of confirming the subscription state and triggering a refresh. Let's update that to properly handle the subscription flow and broadcast the updated state:
Modified serviceworker.js code for subscription handling
function onMessageReceivedSubscribe() { self.registration.pushManager.subscribe({ userVisibleOnly: true }) .then((pushSubscription) => { if (!pushSubscription) { broadcastReply(WorkerMessengerCommand.AMP_SUBSCRIBE, false); onMessageReceivedSubscriptionState(); // Trigger state refresh return; } return self.registration.pushManager.permissionState(pushSubscription.options); }) .then((permissionState) => { if (permissionState) { const isSubscribed = permissionState === 'granted'; broadcastReply(WorkerMessengerCommand.AMP_SUBSCRIBE, isSubscribed); onMessageReceivedSubscriptionState(); // Force component to refresh visibility } }) .catch((error) => { // Handle permission denial explicitly if (error.name === 'NotAllowedError') { broadcastReply(WorkerMessengerCommand.AMP_SUBSCRIPTION_STATE, false); } console.error('Subscription failed:', error); }); }
Problem 2: Subscribe button stays visible after permission denial
You need to:
- Update the subscription state checker to detect when permissions are denied
- Add a dedicated widget for the "denied" state in your HTML
Updated subscription state checker in serviceworker.js
function onMessageReceivedSubscriptionState() { let retrievedPushSubscription = null; self.registration.pushManager .getSubscription() .then((pushSubscription) => { retrievedPushSubscription = pushSubscription; // Always fetch permission state, even if no subscription exists return self.registration.pushManager.permissionState({ userVisibleOnly: true }); }) .then((permissionState) => { console.log('Permission state:', permissionState); const isSubscribed = !!retrievedPushSubscription && permissionState === 'granted'; broadcastReply(WorkerMessengerCommand.AMP_SUBSCRIPTION_STATE, isSubscribed); // This reply tells AMP whether the user is subscribed, which drives visibility changes }); }
Updated amp.html with multi-state widgets
Add widgets for all three possible states so the component knows what to show in each scenario:
<!-- Unsubscribed state (default) --> <amp-web-push-widget visibility="unsubscribed" layout="fixed" width="245" height="45"> <button class="subscribe" on="tap:amp-web-push.subscribe"> <amp-img class="subscribe-icon" width="24" height="24" layout="fixed" src="data:image/svg+xml;base64,PHN2ZyBjbGFzcz0ic3Vic2NyaWJlLWljb24iIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMS44NCAxOS44ODdIMS4yMnMtLjk0Ny0uMDk0LS45NDctLjk5NWMwLS45LjgwNi0uOTQ4LjgwNi0uOTQ4czMuMTctMS41MTcgMy4xNy0yLjYwOGMwLTEuMDktLjUyLTEuODUtLjUyLTYuMzA1czIuODUtNy44NyA2LjI2LTcuODdjMCAwIC40NzMtMS4xMzQgMS44NS0xLjEzNCAxLjMyNSAwIDEuOCAxLjEzNyAxLjggMS4xMzcgMy40MTMgMCA2LjI2IDMuNDE4IDYuMjYgNy44NyAwIDQuNDYtLjQ3NyA1LjIyLS40NzcgNi4zMSAwIDEuMDkgMy4xNzYgMi42MDcgMy4xNzYgMi42MDdzLjgxLjA0Ni44MS45NDdjMCAuODUzLS45OTYuOTk1LS45OTYuOTk1SDExLjg0ek04IDIwLjk3N2g3LjExcy0uNDkgMi45ODctMy41MyAyLjk4N1M4IDIwLjk3OCA4IDIwLjk3OHoiIGZpbGw9IiNGRkYiLz48L3N2Zz4="> </amp-img> Subscribe to notifications </button> </amp-web-push-widget> <!-- Subscribed state --> <amp-web-push-widget visibility="subscribed" layout="fixed" width="245" height="45"> <button class="unsubscribe" on="tap:amp-web-push.unsubscribe"> Unsubscribe from notifications </button> </amp-web-push-widget> <!-- Permission denied state --> <amp-web-push-widget visibility="denied" layout="fixed" width="245" height="45"> <div class="permission-denied-text"> Notifications are blocked. Please enable them in your browser settings. </div> </amp-web-push-widget> <amp-web-push id="amp-web-push" layout="nodisplay" helper-iframe-url="https://..." permission-dialog-url="https://..." service-worker-url="https://..." > </amp-web-push>
Key Notes:
- Ensure your
helper-iframe-url,permission-dialog-url, andservice-worker-urlare correctly configured to match your domain (AMP has strict cross-origin rules for these resources). - The updated service worker now explicitly broadcasts state changes after subscription attempts, which triggers the AMP component to update its visibility.
- Adding the "denied" state widget ensures users see a relevant message instead of the subscribe button when permissions are blocked.
内容的提问来源于stack exchange,提问作者Pivil
相关产品推荐
相关产品推荐

