You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

订阅后如何更新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:

  1. Update the subscription state checker to detect when permissions are denied
  2. 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, and service-worker-url are 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:37:38