3

Firebase Cloud Messaging + Serviceワーカーを使用してバックグラウンドプッシュ通知を処理しています。 (一部のデータ+ URLが含まれている)の通知をクリックするとServiceWorker WindowClient.navigate promiseが拒否されました

は、私が欲しいのいずれか:

  • フォーカスそれがURLに必要なURLにすでに
  • 移動しますし、それを集中した場合、ウィンドウ上記の条件のどちらも

ポイント1とSW以下のコードで3作品を満たしている場合は、既にURLへ

  • 開きます新しいウィンドウで開いているアクティブなタブがある場合。

    何らかの理由で、ポイント2が機能していません。 client.navigate()約束はして拒否されている:

    Uncaught (in promise) TypeError: Cannot navigate to URL: http://localhost:4200/tasks/-KMcCHZdQ2YKCgTA4ddd

    私はそれが原因HTTPSの欠如にあるかもしれないと思ったが、SWを開発しながら、ローカルホストをホワイトリストに登録されているかのように私の読書からそれが表示されます。

    firebaseメッセージング-sw.js:私のSWコードの大部分はから取られ

    // 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.github.com/vibgy/0c5f51a8c5756a5c408da214da5aa7b0

  • 答えて

    3

    私はあなたのclients.matchAll()からincludeUncontrolled: trueを残してお勧めします。

    あなたが担当しているWindowClientには、現在のサービスワーカーがアクティブなサービスワーカーでない可能性があります。項目the specification for WindowClient.navigate() 4のとおり:

    コンテキストオブジェクトの関連するサービスワーカークライアントのアクティブ サービスワーカーはTypeErrorで拒否約束を返し、コンテキストオブジェクトの関連するグローバルオブジェクトの サービスワーカーではない場合。

    クライアントがサービスワーカーによって現在制御されていることを確認したときに問題を再現できる場合は、何か他のことが起こっている可能性がありますが、それが最初の手順です。

    +2

    さらにJeffさんのコメントに、firebase-messaging-sw.jsは確実に*ページを制御しません。これは設計によるものです。この振る舞いが必要な場合は、カスタムサービスワーカー登録を 'messaging.useServiceWorker(<ここに登録>)'に渡すことができます。このサービスワーカー登録は、元のページをすべて制御し、navigate()呼び出しの使用を許可します。 –

    +1

    @Jeff - 'clients.matchAll()'が制御されていないウィンドウを含んでいない限り、WindowClientsを返さなかったことがわかりました。 提案をいただき、ありがとうございました。これがどのようになっているかをお知らせします。 – rabhw

    +1

    @ GuntFaceこれについて詳しく説明できますか?私は自分のserviceworkerをmessaging.useServiceWorkerに渡しましたが、同じエラーが発生します。 – user2145184

    関連する問題