Сервисный работник отправляет несколько уведомлений - PullRequest
0 голосов
/ 17 мая 2018

Я создал плагин WordPress для веб-push-уведомлений, где пользователь может разрешить уведомление и подписаться на наш веб-сайт.Пользователь получит уведомление на рабочем столе, когда мы опубликуем новый пост.У меня есть работник службы поддержки пользователей.

Проблема в том, что когда пользователь подписывается, он получает приветственное уведомление со ссылкой на щелчок уведомления на нашем веб-сайте, который работает отлично, но когда мы публикуемпочтовые пользователи получают несколько уведомлений.Например, некоторые пользователи получают два уведомления, а некоторые получают более двух, и во всех этих уведомлениях у них есть только одно уведомление со ссылкой, по которой они перенаправляют на страницу сообщений, а другие уведомления не имеют ссылки.

Ниже приведен файл service-worker.js:

self.addEventListener('install', function (event) {
    console.log('installed!');
});
self.addEventListener('activate', function (event) {
    console.log('activated!');
});
self.addEventListener('message', function (event) {
});

Затем мы сгенерировали токен с помощью файла generate-token.js, который находится ниже:

var obj = JSON.parse(notifyonnewpost.ajax_data);
var config = {
            apiKey: obj.apiKey,
            authDomain: obj.authDomain,
            databaseURL: obj.databaseURL,
            projectId: obj.projectId,
            storageBucket: obj.storageBucket,
            messagingSenderId: obj.messagingSenderId,
        };
        firebase.initializeApp(config);
        const messaging = firebase.messaging();
        var permission = Notification.permission;
        if (permission == "default")
        {
            window.localStorage.setItem('UDID', 0);
        }
        var UDID = window.localStorage.getItem('UDID');
        var eww_epush = obj.eww_epush;
        var check_mob = isMobileDevice();
        if(!check_mob)
        {
            if (UDID != guid())
            {
                window.localStorage.setItem('UDID', guid());
                if ('serviceWorker' in navigator) {
                    var myId = obj.messagingSenderId;
                    navigator.serviceWorker.register(notifyonnewpost.message_sw_path+'?messagingSenderId=' + myId+'&notifyappjs=' +notifyonnewpost.notify_app_path+'&notifymsgjs=' +notifyonnewpost.notify_msg_path).then(function(reg) {
                        console.log("SW registration succeeded. Scope is " + reg.scope);
                        messaging.useServiceWorker(reg);
                        reg.update();
                    }).catch(function(err) {
                        console.error("SW registration failed with error " + err);
                    });
                }
                requestPermission();
            }
        }
        else if(check_mob && eww_epush)
        {
            if (UDID != guid())
            {
                window.localStorage.setItem('UDID', guid());
                if ('serviceWorker' in navigator) {
                    var myId = obj.messagingSenderId;
                    navigator.serviceWorker.register(notifyonnewpost.message_sw_path+'?messagingSenderId=' + myId+'&notifyappjs=' +notifyonnewpost.notify_app_path+'&notifymsgjs=' +notifyonnewpost.notify_msg_path).then(function(reg) {
                        console.log("SW registration succeeded. Scope is " + reg.scope);
                        messaging.useServiceWorker(reg);
                        reg.update();
                    }).catch(function(err) {
                        console.error("SW registration failed with error " + err);
                    });
                }
                requestPermission();
            }
        }
        const tokenDivId = 'divToken';
        const permissionDivId = 'permission_div';
        messaging.onTokenRefresh(function() {
            messaging.getToken()
                .then(function(refreshedToken) {
                    console.log('Token refreshed.');
                    setTokenSentToServer(false);
                    sendTokenToServer(refreshedToken);
                })
                .catch(function(err) {
                    console.log('Unable to retrieve refreshed token ', err);
                    showToken('Unable to retrieve refreshed token ', err);
                });
        });
        messaging.onMessage(function(payload) {
            appendMessage(payload);
        });
        function resetUserInterface() {
            console.log('Loading the token...');
            messaging.getToken()
                .then(function(currentToken) {
                    if (currentToken) {
                        sendTokenToServer(currentToken);
                        updateUIForPushEnabled(currentToken);
                    } else {
                        console.log('Request permission to generate Token.');
                        updateUIForPushPermissionRequired();
                        setTokenSentToServer(false);
                    }
                })
                .catch(function(err) {
                    console.log('Error occurred while retrieving token. ', err);
                    setTokenSentToServer(false);
                });
        }
        function sendTokenToServer(currentToken) {
            if (!isTokenSentToServer()) {
                console.log('Sending token to the server...');
                setTokenSentToServer(true);
            } else {
                console.log('Token sent to server!');
            }
        }
        function isTokenSentToServer() {
            if (window.localStorage.getItem('sentToServer') == 1) {
                return true;
            }
            return false;
        }
        function setTokenSentToServer(sent) {
            window.localStorage.setItem('sentToServer', sent ? 1 : 0);
        }
        function requestPermission() {
            console.log('Requesting permission...');
            messaging.requestPermission()
                .then(function(event) {
                    console.log(event);
                    console.log('Notification permission granted.');
                    resetUserInterface();
                })
                .catch(function(err) {
                    console.log('Unable to get permission for notification.', err);
                });
        }
        function deleteToken() {
            messaging.getToken()
                .then(function(currentToken) {
                    messaging.deleteToken(currentToken)
                        .then(function() {
                            console.log('Token deleted.');
                            setTokenSentToServer(false);
                        })
                        .catch(function(err) {
                            console.log('Unable to delete token. ', err);
                        });
                })
                .catch(function(err) {
                    console.log('Error retrieving token. ', err);
                    showToken('Error retrieving token. ', err);
                });
        }
        function updateUIForPushEnabled(currentToken) {
            var id = guid();
            fetch(notifyonnewpost.ajaxurl, {
                mode : 'no-cors',
                method: 'POST',
                data:"action=fwpn_push_welcome&nonce="+notifyonnewpost.nonce,
                body: JSON.stringify({
                    token: currentToken,
                    id: id
                })
            })
        }
        function guid() {
            var nav = window.navigator;
            var screen = window.screen;
            var guid = nav.mimeTypes.length;
            guid += nav.userAgent.replace(/\D+/g, '');
            guid += nav.plugins.length;
            guid += screen.height || '';
            guid += screen.width || '';
            guid += screen.pixelDepth || '';
            return guid;
        }
function isMobileDevice() {
    return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
};

Затем мы использовалиобмен сообщениями в firebase для отправки push-уведомлений пользователю, который находится ниже firebase-messaging-sw.js

get_sw_url_parameters ('notifyappjs');// загрузил этот js: https://www.gstatic.com/firebasejs/3.7.4/firebase-app.js get_sw_url_parameters ('notifymsgjs');// загрузил js: https://www.gstatic.com/firebasejs/3.7.4/firebase-messaging.js

var notifyappjs = get_sw_url_parameters( 'notifyappjs' );
var notifymsgjs = get_sw_url_parameters( 'notifymsgjs' );
 importScripts(notifyappjs);
 importScripts(notifymsgjs);
 var messagingSenderId="";
  var myId = get_sw_url_parameters( 'messagingSenderId' );
function get_sw_url_parameters( param ) {
    var vars = {};
    self.location.href.replace( self.location.hash, '' ).replace( 
        /[?&]+([^=&]+)=?([^&]*)?/gi, 
        function( m, key, value ) { 
            vars[key] = value !== undefined ? value : '';
        }
    );
    if( param ) {
        return vars[param] ? vars[param] : null;    
    }
    return vars;
}
firebase.initializeApp({
    'messagingSenderId': myId  
});
const initMessaging = firebase.messaging();
self.addEventListener('push', function (event) {
    var eventData = event.data.text();
    var obj = JSON.parse(eventData); 
    var title = obj.notification.title;
    var  tag = 'FWPN_TAG';
    var options = {
        body: obj.notification.body, 
        icon: obj.notification.icon,
        image: obj.notification.sound,
        data: obj.data,
    };
    event.waitUntil(self.registration.showNotification(title, options,tag));
});
self.addEventListener('notificationclick', function (event) {
    event.notification.close();
    event.waitUntil(
      clients.openWindow(event.notification.data.link)
    );
});
self.addEventListener('pushsubscriptionchange', function (event) {
    const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
    event.waitUntil(
      self.registration.pushManager.subscribe({
          userVisibleOnly: true,
          applicationServerKey: applicationServerKey
      })
      .then(function (newSubscription) {
          console.log('Push subscription is changed. New Subscription is: ', newSubscription);
      })
    );
});

Это php-код для отправки push-уведомления при публикации нового сообщения:

function fwpn_send_push($token,$msg)
      {
            $registrationIds = $token;
            $fields = array(
                'to' => $registrationIds,
                'notification' => $msg,
                'data'=>array('link'=> get_permalink($post_id),'tag' => time()),
            );
            $headers = array('Authorization' => 'key=' . get_option('Serverkey'), 'Content-Type' => 'application/json');
            $fwpn_remote_args = array(
                'method'        => 'POST',
                'timeout'       => 45,
                'redirection'   => 5,
                'httpversion'   => '1.0',
                'blocking'      => true,    
                'body' => json_encode($fields),
                'headers' => $headers,
                'cookies' => array()
              );
          $response = wp_remote_post( 'https://fcm.googleapis.com/fcm/send', $fwpn_remote_args );
      }

Ниже будет запущен хук и вызовфункция для публикации нового поста, и из этой функции я вызвал fwpn_send_push () .

add_action( 'publish_post', array( $this, 'fwpn_post_published_notification' ), 10, 2 );

 function fwpn_post_published_notification($ID, $post)
      {
        $original_post_status = $_POST[ 'original_post_status' ];
        if($original_post_status == 'auto-draft' || $original_post_status == 'draft' )
        {
            $current_post_id = $post->ID;
            if($_POST[ 'do_not_send_push_notifications_for_this_post' ] == 1)
            {
              $push_post_data = update_post_meta( $current_post_id, 'do_not_send_push_notifications_for_this_post', $_POST[ 'do_not_send_push_notifications_for_this_post' ] );
            }
            else
            {
              $push_post_data = update_post_meta( $current_post_id, 'do_not_send_push_notifications_for_this_post', 0 );
            }
            $display_notification = get_post_meta( $current_post_id, 'do_not_send_push_notifications_for_this_post', true );
            if($display_notification == 0)
            {    
                global $wpdb;
                $prifix=$wpdb->prefix;
                $current_data     = $wpdb->get_results("SELECT * FROM ".$prifix."push_notification");
                $post_result      = array(
                "post_type" => 'post',
                "post_status" => "publish",
                "posts_per_page" => 1,
                "order" => "DESC",
                "orderby" => "date"
                );
                $post_result_data = new WP_Query($post_result);
                $post_id=$post_result_data->post->ID;
                $thumb = $this->fwpn_get_thumb_url($post_id);
                $message = $this->fwpn_get_push_message($post_result_data,$thumb);               
                foreach ($current_data as $value) {
                   $this->fwpn_send_push($value->authSecret,$message);
                }
            }
          }
      }
...