当前位置: 首页 > 知识库问答 >
问题:

ServiceWorker WindowClient。拒绝promise

唐向荣
2023-03-14

我正在使用Firebase云消息服务辅助角色处理后台推送通知。

当通知(其中包含一些数据的URL)被点击,我想要么:

  • 焦点窗口,如果它已经在所需的URL
  • 导航到URL并聚焦它,如果已经有一个活动的选项卡打开
  • 如果上述条件都不满足,则打开URL的新窗口

点1和3与下面的SW代码一起工作。

出于某种原因,第2点不起作用。客户端。navigate()promise被拒绝,原因是:

未捕获(在promise)TypeError:无法导航到URL:http://localhost:4200/tasks/-KMcCHZdQ2YKCgTA4ddd

我认为这可能是由于缺少https,但从我的阅读来看,似乎localhost在使用SW开发时被列入了白名单。

firebase消息软件。js:

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/3.5.3/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.5.3/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
  'messagingSenderId': 'XXXX'
});

const messaging = firebase.messaging();

messaging.setBackgroundMessageHandler(payload => {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  let notificationData = JSON.parse(payload.data.notification);
  const notificationOptions = {
    body: notificationData.body,
    data: {
      clickUrl: notificationData.clickUrl
    }
  };

  return self.registration.showNotification(notificationData.title,
    notificationOptions);
});

self.addEventListener('notificationclick', event => {
  console.log('[firebase-messaging-sw.js] Notification OnClick: ', event);

  // Android doesn’t close the notification when you click on it
  // See: http://crbug.com/463146
  event.notification.close();

  // This looks to see if the current is already open and
  // focuses if it is
  event.notification.close();
  let validUrls = /localhost:4200/;
  let newUrl = event.notification.data.clickUrl || '';

  function endsWith(str, suffix) {
    return str.indexOf(suffix, str.length - suffix.length) !== -1;
  }

  event.waitUntil(
    clients.matchAll({
      includeUncontrolled: true,
      type: 'window'
    })
    .then(windowClients => {
      for (let i = 0; i < windowClients.length; i++) {
        let client = windowClients[i];
        if (validUrls.test(client.url) && 'focus' in client) {
          if (endsWith(client.url, newUrl)) {
            console.log('URL already open, focusing.');
            return client.focus();
          } else {
            console.log('Navigate to URL and focus', client.url, newUrl);
            return client.navigate(newUrl).then(client => client.focus());
          }
        }
      }

      if (clients.openWindow) {
        console.log('Opening new window', newUrl);
        return clients.openWindow(newUrl);
      }
    })
  );

});

我的绝大多数软件代码取自:https://gist.html" target="_blank">github.com/vibgy/0c5f51a8c5756a5c408da214da5aa7b0

共有2个答案

柯鸿振
2023-03-14

这对我很有效:

1-创建一个可观察的,并确保在消息传递API解决之前不调用它。

2、自己注册服务人员,先检查是否已经注册

3-呼叫事件。waitill(clients.claim());在你的服务人员

private isMessagingInitialized$: Subject<void>;

constructor(private firebaseApp: firebase.app.App) {
    navigator.serviceWorker.getRegistration('/').then(registration => {
        if (registration) {
            // optionally update your service worker to the latest firebase-messaging-sw.js
            registration.update().then(() => { 
                firebase.messaging(this.firebaseApp).useServiceWorker(registration);
                this.isMessagingInitialized$.next();
            });
        }
        else {
            navigator.serviceWorker.register('firebase-messaging-sw.js', { scope:'/'}).then(
                registration => {
                    firebase.messaging(this.firebaseApp).useServiceWorker(registration);
                    this.isMessagingInitialized$.next();
                }
            );

        }
    });
    
    this.isMessagingInitialized$.subscribe(
        () => {
            firebase.messaging(this.firebaseApp).usePublicVapidKey('Your public api key');
            firebase.messaging(this.firebaseApp).onTokenRefresh(() => {
                this.getToken().subscribe((token: string) => {

                })
            });
            firebase.messaging(this.firebaseApp).onMessage((payload: any) => {

            });
        }
    );
}

>

  • firebase-messaging-sw.js

      self.addEventListener('notificationclick', function (event) {
    
      event.notification.close();
    
      switch (event.action) {
          case 'close': {
              break;
          }
          default: {
              event.waitUntil(clients.claim());// this 
              event.waitUntil(clients.matchAll({
                  includeUncontrolled: true,
                  type: "window"
              }).then(function (clientList) {
              ...
              clientList[i].navigate('you url');
              ...
              }
          }
      }
    

    }

  • 巫马山
    2023-03-14

    我建议不要让客户使用includeUncontrolled:true。matchAll()

    正在操作的WindowClient可能没有当前服务辅助角色作为其活动服务辅助角色。根据WindowClient.navigate()规范中的第4项:

    如果上下文对象的关联服务辅助角色客户端的活动服务辅助角色不是上下文对象的相关全局对象的服务辅助角色,则返回拒绝的promise,并使用TypeError

    如果您可以在确定客户端当前由服务人员控制的情况下重现该问题,那么可能会发生其他情况,但这是我尝试的第一步。

     类似资料:
    • 不管我使用什么端口或主机,Net.CreateConnection似乎总是拒绝连接。我想是有什么东西阻碍了它的打开,但我不知道是什么原因造成的。 代码: 输出:

    • 我正在尝试编写一个jasmine测试,它有一个间谍, 是一个许诺列表。前几次承诺是拒绝,最后一次是成功。虽然测试顺利通过,但Node抱怨如下: 我的代码非常直接:我创建一个间谍,将它注入到我的代码中,调用我的代码,这将循环调用我的间谍直到它不拒绝,然后监视它被调用了5次。间谍是这样的: 被测试的代码在它的链中最后一个空的 来验证我没有引起那里的问题。AFICT,问题是Node看到我在执行 ,并认为

    • 我按照这个链接创建我的第一个docker映像,它成功了,现在我正试图从这个链接将这个映像推送到我的docker存储库中。但每当我试图将此图像推入存储库时,就会出现这种类型的错误。 有人能给我一些关于这个问题的提示吗?任何帮助都将不胜感激。 注意:我已成功登录docker

    • 我读过类似的问题,答案都围绕着纠正这样的一行: 不幸的是,我读过的书中没有什么能解决这个问题。 在我的index.html中,我有: 在我的app.js im中使用: 当我访问该页时,控制台记录 LocalHost/:1拒绝应用来自“http://localhost:3000/public/css/style.css”的样式,因为它的MIME类型(“text/html”)不是受支持的样式表MIME

    • 问题内容: 在我的android项目(目标SDK版本23)中,我想拒绝来电。我知道对此有很多疑问,特别是 1 如何将com.android.internal.telephony.ITelephony导入Android应用程序 2 如何在Android中以编程方式拒绝通话 在第一个链接中,建议的解决方案是在接口上使用反射,因为它是内部接口。但是此解决方案使用权限,该权限只能授予系统应用程序,因此无论

    • 当我创建新用户或授予现有特权,我得到了这个错误: 授予所有表上的权限ok(信息\u架构除外),在此表上我得到了拒绝访问错误。我怎么能修理?转储所有数据库,删除所有数据库,然后从转储还原?