首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果用户离线,如何对推送通知消息进行排队,并在用户重新上线时进行推送?

如果用户离线,如何对推送通知消息进行排队,并在用户重新上线时进行推送?
EN

Stack Overflow用户
提问于 2020-11-30 03:04:26
回答 1查看 36关注 0票数 0

我使用javascripts构建了一个推送通知服务,一切似乎都很好,工作正常,但只有一个问题,如果我在用户离线时推送消息,如果用户重新在线,消息将永远不会传递。我的代码如下: seviceWorker.js

代码语言:javascript
复制
'use strict';

const pushData = event.data.text();
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
var data = JSON.parse(pushData);
const title = 'Test';
const options = {
  body: 'This is a test',
  icon: 'logo.png',
  badge: 'logo.png',
  sound:'juntos-607.mp3',
  image:data.image,
  vibrate: [200, 100, 200, 100, 200, 100, 400],
  requireInteraction: true
};

event.waitUntil(self.registration.showNotification(title, options));
  // Handle click event
self.addEventListener('notificationclick', function(event) {
console.log('[Service Worker] Notification click received.');

event.notification.close();

event.waitUntil(
  clients.openWindow('www.test.com')
);
});
});

service.js

代码语言:javascript
复制
'use strict';

const applicationServerPublicKey = 'some key';

const pushButton = document.querySelector('.js-push-btn');

let isSubscribed = false;
let swRegistration = null;

function urlB64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');

 const rawData = window.atob(base64);
 const outputArray = new Uint8Array(rawData.length);

 for (let i = 0; i < rawData.length; ++i) {
 outputArray[i] = rawData.charCodeAt(i);
 }
 return outputArray;
 }
 // Checking if serviceworker and pushManager is active
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push are supported');

navigator.serviceWorker.register('serviceWorker.js')
.then(function(swReg) {
console.log('Service Worker is registered', swReg);

swRegistration = swReg;
initializeUI();
})
.catch(function(error) {
console.error('Service Worker Error', error);
});
} else {
console.warn('Push messaging is not supported');
pushButton.textContent = 'Push Not Supported';
}

function initializeUI() {
pushButton.addEventListener('click', function() {
pushButton.disabled = true;
if (isSubscribed) {
  // TODO: Unsubscribe user
  unsubscribeUser();
} else {
  subscribeUser();
}
});
// Set the initial subscription value
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
isSubscribed = !(subscription === null);

if (isSubscribed) {
  console.log('User IS subscribed.');
} else {
  console.log('User is NOT subscribed.');
}

updateBtn();
});
}

function updateBtn() {
if (Notification.permission === 'denied') {
pushButton.textContent = 'Push Messaging Blocked';
pushButton.disabled = true;
updateSubscriptionOnServer(null);
return;
}
if (isSubscribed) {
pushButton.textContent = 'Disable Push Messaging';
} else {
pushButton.textContent = 'Enable Push Messaging';
}

pushButton.disabled = false;
}



function subscribeUser() {
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function(subscription) {
console.log('User is subscribed.');

updateSubscriptionOnServer(subscription);

isSubscribed = true;

updateBtn();
})
.catch(function(error) {
console.error('Failed to subscribe the user: ', error);
updateBtn();
});
}

function updateSubscriptionOnServer(subscription) {
// TODO: Send subscription to application server

const subscriptionJson = document.querySelector('.js-subscription-json');
const subscriptionDetails =
document.querySelector('.js-subscription-details');

if (subscription) {
subscriptionJson.textContent = JSON.stringify(subscription);
subscriptionDetails.classList.remove('is-invisible');

// Send data to database
var datastring = JSON.stringify(subscription)
$.ajax({
  url : "/push-api", // Url of backend (can be python, php, etc..)
  type: "POST", // data type (can be get, post, put, delete)
  data : datastring, // data in json format
  contentType: 'application/json',
  async : false, // enable or disable async (optional, but suggested as false if you need to 
  populate data afterwards)
  success: function(response, textStatus, jqXHR) {
    console.log(response);
  },
  error: function (jqXHR, textStatus, errorThrown) {
  console.log(jqXHR);
      console.log(textStatus);
      console.log(errorThrown);
  }
  });

  } else {
  subscriptionDetails.classList.add('is-invisible');
  }
  }

  // Get user subcription
  function unsubscribeUser() {
  swRegistration.pushManager.getSubscription()
  .then(function(subscription) {
  if (subscription) {
  // TODO: Tell application server to delete subscription
   // Send data to database
  var datastring = JSON.stringify(subscription)
  $.ajax({
  url : "/delete-push-api", // Url of backend (can be python, php, etc..)
  type: "POST", // data type (can be get, post, put, delete)
  data : datastring, // data in json format
  contentType: 'application/json',
  async : false, // enable or disable async (optional, but suggested as false if you need to 
  populate data afterwards)
  success: function(response, textStatus, jqXHR) {
    console.log(response);
  },
  error: function (jqXHR, textStatus, errorThrown) {
  console.log(jqXHR);
      console.log(textStatus);
      console.log(errorThrown);
  }
  });
  return subscription.unsubscribe();
  }
  })
 .catch(function(error) {
 console.log('Error unsubscribing', error);
 })
 .then(function() {
updateSubscriptionOnServer(null);

console.log('User is unsubscribed.');
isSubscribed = false;

updateBtn();
});
}

这是从google codelab的文档中构建的。谢谢

EN

回答 1

Stack Overflow用户

发布于 2020-11-30 03:09:35

这是一件基本的事情,因为当用户不在你的网站上时,你的代码永远不会工作。要解决此问题,您可以使用Firebase云消息服务。Firebase FCM是免费的。FCM用于在移动应用和Web上推送通知。您可以在here上找到详细的文档

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65063995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档