I have successfully implemented GCM and ServiceWorkers to receive push-notification.
My problem
Whenever there is a SOS update, I am sending a HTTP request to gcm-http which then shows up a normal notification on Google Chrome but without any payload or data.
According to Google Developers Doc, chrome cannot receive payload/data, so one have to manually fetch the notification from the backend when push event is triggered.
So to fetch the data I am requesting an url on my backend (in django) to send me the notification data. But problem lies here how will I know which notification's data I have to send from my database/model?
Note:- I am not maintaining a different database table/model
to determine notifications read by the client, since its an SOS update and read/unread is not required.
Workaround which is not working:-
I can set a cookie on client's browser and on backend can get next notification (below is the code)
class GetSOSNotification(View):
notif_id = 0
def get(self, request):
if 'last_notif_id' in request.COOKIES:
notif_id = request.COOKIES.get('last_notif_id') + 1
sos = SOSUpdate.objects.get(id=notif_id)
else:
sos = SOSUpdate.objects.order_by('-timestamp').filter()[0]
notif_id = sos.id
data = dict()
data['notification'] = dict()
if sos.get_condition_display() and sos.get_subject_display():
data['notification']['title'] = sos.polling_station.name + " " + sos.get_subject_display() + " " + sos.get_condition_display()
elif sos.get_condition_display():
data['notification']['title'] = sos.polling_station.name + " " + sos.get_condition_display()
elif sos.get_subject_display():
data['notification']['title'] = sos.polling_station.name + " " + sos.get_subject_display()
else:
data['notification']['title'] = sos.polling_station.name + " SOS Alert!"
if sos.message:
data['notification']['message'] = sos.message
else:
data['notification']['message'] = "Please click here to check the details."
data['notification']['notif_id'] = notif_id
return JsonResponse(data)
but, I have to return JSON response, and therefoe I can't set cookie from server-side, therefore I planned to use data['notification']['notif_id']
on client-side (i.e., Javascript) to set cookie.
My SW.js's snippet looks like :
self.addEventListener('push', function(event) {
console.log('Push message', event);
event.waitUntil(
fetch("//localhost/get_sos_notification/").then(function(response){
if(response.status!=200){
console.log('Looks like there was a problem. Status Code: ' + response.status);
throw new Error();
}
return response.json().then(function(data){
if(data.error || !data.notification){
console.error('The API returned an error.', data.error);
throw new Error();
}
var title = data.notification.title;
var message = data.notification.message;
var icon = '//localhost/static/main/images/push-notification.png';
var notificationTag = data.notification.tag;
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
});
}).catch(function(err){
console.log('Unable to retrieve data', err);
var title = 'SOS - Update';
var message = 'We were unable to get the information, please click here to know the real message.';
var icon = '//localhost/static/main/images/push-notification.png';
var notificationTag = 'notification-error';
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
})
);
});
But I am not able to do document.cookie = last_notif_id=data.notification.notif_id
at the place where I am handling received notification data (if successfully received), because the JS script is giving error Unable to retrieve data ReferenceError: document is not defined at http://localhost/static/main/js/sw.js
Additional information: //localhost/get_sos_notification/
is a GET request, returns JSON, and is mapped to class GetSOSNotification(View)
I have googled and searched SO a lot, but haven't got any solution.
Thanks in advance.