2017-06-02 7 views
1

FCM APIを使用してブラウザからプッシュ通知を受信して​​います。 firebase-messaging-sw.jsは正常に動作し、Webアプリケーションがバックグラウンドの場合にはmessaging.setBackgroundMessageHandlerが1回だけ発生します。しかし、アプリケーションがフォアグラウンドになっているときは、ブラウザタブごとに1つの通知が届いています(3つのタブでアプリが開かれている場合、3つの通知を受け取ります)。私はこの問題への言及を見つけることができないので、私はこれをどのように処理すべきかと思います。これは、フォアグラウンドのFCMメッセージのコードです。FCMのブラウザでフォアグラウンドの各タブごとに1つの通知を受信

import NotificationActionCreators from '../actions/NotificationActionCreators'; 
import NotificationService from './NotificationService'; 
import LocalStorageService from './LocalStorageService'; 
import { FIREBASE_SCRIPT, FCM_URL, FCM_API_KEY, FCM_AUTH_DOMAIN, FCM_PROJECT_ID, FCM_SENDER_ID, PUSH_PUBLIC_KEY } from '../constants/Constants'; 


class ServiceWorkerService { 

constructor() { 
    this._messaging = null; 
    this._subscriptionData = null; 
} 

// This function is called once 
init() { 
    this.loadScript(FIREBASE_SCRIPT,() => this.onFirebaseLoaded()); 
} 

onFirebaseLoaded() { 
    // Initialize Firebase 
    let config = { 
     apiKey: FCM_API_KEY, 
     authDomain: FCM_AUTH_DOMAIN, 
     projectId: FCM_PROJECT_ID, 
     messagingSenderId: FCM_SENDER_ID 
    }; 
    firebase.initializeApp(config); 
    this._messaging = firebase.messaging(); 

    this.requestPermission(); 

    // Callback fired if Instance ID token is updated. 
    this._messaging.onTokenRefresh(() => { 
     this._messaging.getToken() 
      .then((refreshedToken) => { 
       console.log('Token refreshed.'); 
       NotificationActionCreators.unSubscribe(this._subscriptionData).then(() => { 
        // Indicate that the new Instance ID token has not yet been sent to the 
        // app server. 
        this.setTokenSentToServer(false); 
        // Send Instance ID token to app server. 
        this.sendTokenToServer(refreshedToken); 
       },() => console.log('Error unsubscribing user')); 
      }) 
      .catch(function(err) { 
       console.log('Unable to retrieve refreshed token ', err); 
      }); 
    }); 

    // Handle incoming messages. 
    // *** THIS IS FIRED ONCE PER TAB *** 
    this._messaging.onMessage(function(payload) { 
     console.log("Message received. ", payload); 
     const data = payload.data; 

     NotificationActionCreators.notify(data); 
    }); 
} 

requestPermission() { 
    console.log('Requesting permission...'); 
    return this._messaging.requestPermission() 
     .then(() => { 
      console.log('Notification permission granted.'); 
      this.getToken(); 
     }) 
     .catch(function(err) { 
      console.log('Unable to get permission to notify.', err); 
     }); 
} 

getToken() { 
    // Get Instance ID token. Initially this makes a network call, once retrieved 
    // subsequent calls to getToken will return from cache. 
    return this._messaging.getToken() 
     .then((currentToken) => { 
      if (currentToken) { 
       this.sendTokenToServer(currentToken); 
      } else { 
       // Show permission request. 
       console.log('No Instance ID token available. Request permission to generate one.'); 
       this.setTokenSentToServer(false); 
      } 
     }) 
     .catch(function(err) { 
      console.log('An error occurred while retrieving token. ', err); 
      this.setTokenSentToServer(false); 
     }); 
} 

sendTokenToServer(currentToken) { 
    const subscriptionData = { 
     endpoint: FCM_URL + currentToken, 
     platform: 'Web' 
    }; 
    if (!this.isTokenSentToServer()) { 
     console.log('Sending token to server...'); 
     this.updateSubscriptionOnServer(subscriptionData); 
    } else { 
     console.log('Token already sent to server so won\'t send it again ' + 
      'unless it changes'); 
    } 
    this._subscriptionData = subscriptionData; 
} 

isTokenSentToServer() { 
    return LocalStorageService.get('sentToServer') == 1; 
} 

setTokenSentToServer(sent) { 
    LocalStorageService.set('sentToServer', sent ? 1 : 0); 
} 

updateSubscriptionOnServer(subscriptionData) { 
    if (subscriptionData) { 
     NotificationActionCreators.subscribe(subscriptionData); 
     this.setTokenSentToServer(true); 
     this._subscriptionData = subscriptionData; 
    } else { 
     console.log('Not subscribed'); 
    } 
} 

unSubscribe() { 
    this.removeSetTokenSentToServer(); 
    return this._messaging.getToken() 
     .then((currentToken) => { 
      return this._messaging.deleteToken(currentToken) 
       .then(() => { 
        console.log('Token deleted.'); 
        return NotificationActionCreators.unSubscribe(this._subscriptionData); 
       }) 
       .catch(function(err) { 
        console.log('Unable to delete token. ', err); 
        return new Promise(function(resolve, reject) { 
         reject(error) 
        }); 
       }); 
     }) 
     .catch(function(err) { 
      console.log('Error retrieving Instance ID token. ', err); 
      return new Promise(function(resolve, reject) { 
       reject(error) 
      }); 
     }); 
    } 
} 

removeSetTokenSentToServer() { 
    LocalStorageService.remove('sentToServer'); 
} 

loadScript = function (url, callback) { 
    let head = document.getElementsByTagName('head')[0]; 
    let script = document.createElement('script'); 
    script.type = 'text/javascript'; 
    script.src = url; 

    script.onload = callback; 

    // Fire the loading 
    head.appendChild(script); 
} 
} 

最初に見つかったタブだけで通知を表示する方法はありますか。

答えて

2

私は、これはチェックして、ランダムな時間とsetTimeoutとローカルストレージに「通知ID」変数を設定することで達成するために見つけた唯一の方法:

this._messaging.onMessage(function(payload) { 
    const data = payload.data; 
    // This prevents to show one notification for each tab 
    setTimeout(() => { 
     if (localStorage.getItem('lastNotificationId')) != parseInt(data.notId)) { 
      localStorage.setItem('lastNotificationId', parseInt(data.notId)) 
      NotificationActionCreators.notify(data); 
     } 
    }, Math.random() * 1000); 
}); 

notIdが送信されますプッシュ通知内にあり、通知の識別子です。

関連する問題