我创建了一个wordpress插件Web推送通知,用户可以在其中允许通知并订阅我们的网站。当我们发布新帖子时,用户将收到桌面通知。我有一个用户服务工作者。
问题在于,当用户订阅时,他们会收到欢迎通知,其中包含点击通知到我们网站的链接,该链接工作正常,但是当我们发布帖子后,用户会收到多个通知。例如,某些用户会收到两个通知,有些会收到两个以上的通知,在所有这些通知中,他们只有一个通知,其中包含重定向到帖子页面的链接,而其他通知没有链接。
以下是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+'¬ifyappjs=' +notifyonnewpost.notify_app_path+'¬ifymsgjs=' +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+'¬ifyappjs=' +notifyonnewpost.notify_app_path+'¬ifymsgjs=' +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消息传递将web推送通知发送给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代码:
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);
}
}
}
}