Assuming:
User has allowed notifications on my website.
Service worker is installed and ready.
User sets a client side reminder to be reminded 24 hours from now.
No backend service or server to push the notification to the user.
How can I trigger a desktop notification if there is no backend server to push that notification? Is this possible?
The service worker will be shutdown by the browser if provided a timeout/interval and the web-alarm/task-scheduler specification is not yet ready for use. Is there no client side only approach to trigger a notification at some designated time in the future?
Is there a desktop notification that is strictly not a "push notification"? A push notification, by nature, is pushed from a server. Can a notification be triggered from the client side?
I do not believe this is possible at this point in time.
Push notifications are specified in RFC8030, from its abstract:
This document describes a simple protocol for the delivery of real-
time events to user agents. This scheme uses HTTP/2 server push.
Which implies the requirement for a server supporting HTTP/2 push.
I do love to rant at Javascript, and I do not seem to be able to find an Javascript implementation of an HTTP2 server to run in the browser (there is for node), which is a shame for me, and would be awesome to mock about.
So, looking for fame, http2-server.js is missing.
You might be able to consider using localStorage. However, this is only beneficial for users that utilize the same device and browser.
Below is a function that kicks off on page load. If you want it to occur periodically throughout a session, you could wrap it into a setInterval and check periodically. This is assuming it needs to be exactly 24 hours later to the millisecond.
// on page load
window.onload = () => {
const dayMs = 24*60*60*1000; // 1 day in milliseconds
const notificationTimer = localStorage.getItem('notificationTimer');
if(notificationTimer){
const sendNotification = (Date.now() - (new Date(notificationTimer)).getTime()) > dayMs;
if(sendNotification){
const notification = new Notification('Displaying next day reminder from yesterday');
}
}
};
When the user selects the next day reminder you can then set the notificationTimer:
localStorage.setItem(notificationTimer, Date.now());
You'd have to make some caveats about the next day reminder not working across browsers or devices, which may or may not be desirable.
As things stand while writing this (3rd Jan 2019):
There is no "desktop notification" that is not strictly "push notification" and works well cross platforms.
It is not possible to trigger a "desktop notification" without your app working in the background.
Service workers are not supposed to use timers and will be shut down.
The Operating System or other utility software may also suggest or even shut down your background application.
There is no client side only approach to trigger your notification at a precise time in the future. There are too many reasons for organisations not allowing this to happen at present.
Your only choice seems to be to use a different Push Notification Service coupled with an external scheduling service that would trigger the external notification based on custom schedules.
Your requirements as I understand them:
Each visitor would need to subscribe to push notifications
Record externally customer preference (for example: using some cloud scheduling)
Use the external scheduling service to trigger the push notification service.
PUSH NOTIFICATIONS are SERVER TRIGGERED not CLIENT REQUESTED
The main point of push notifications is that you should trigger the notification externally to avoid using resources on the end user device. This does not stop you collect notification preferences from users, save this information externally so you can trigger a notification externally when needed.
More information about PWA notification can be found in the following article:
https://developers.google.com/web/fundamentals/codelabs/push-notifications/
As far I know PWA Service Workers should not use timers!
As an alternative to using the PWA notifications, you may want to rightly consider using different notification service. For example FCM https://firebase.google.com/docs/cloud-messaging/
The idea could be to save externally the notification preference of the user and trigger the FCM notification via another cloud service when the scheduled time is reached.
Obviously those notifications will only ever work if the users are connected to the network. However this would have been also the case with any Notification service requiring network access.
I hope the above helps, Cheers and happy codding!
Assuming the notification data on your website will not be sent from the server. Using local storage will be the way to go.
You can store a variable to help track when to show the notification anytime the user hits your website:
localStorage.setItem("lastNotification", Date.now());
So you can have a script that does the following;
function notificationHelper(){
var lastTime = localStorage.getItem("lastNotification");
if(Date.now - lastTime > 86400000){
//Logic to show notication here
//set a new time at the end of the logic
}
//Otherwise Do Nothing
}
Related
I'm building a pwa for a client that will list upcoming tasks for their employees. They will often be in areas with poor mobile service so the intention is that records are downloaded whenever they have data and then loaded locally from indexeddb.
My original intention was to use "periodic sync" until I realised that the maximum refresh time was once every 12 hours.
Next I moved onto regular background sync, with the js app sending a sync request to the service worker, and the service worker running the functionality on ExtendableEvent.waitUntil as in Google's background sync example:
self.addEventListener('sync', function(event) {
if (event.tag == 'myFirstSync') {
event.waitUntil(doSomeStuff());
}
});
What I've found however is that event.waitUntil only seems to re-attempt the call every 5 minutes and I want a much faster refresh rate (more like every 30 seconds).
I kind of have 2 questions - first, is it possible to speed up the retry rate on waitUntil.
Perhaps more importantly, is this even a helpful strategy? It seems to me that my app could just repeatedly call the update function without even bothering the service worker. What advantage do I actually get from background sync?
Is there anything else in the pwa toolkit that would better suit my needs?
The benefit of (regular, "non-periodic") background sync is that the lifetime of the retries extend beyond the lifetime of your web app being open. Once the sync eventually succeeds, you could do something like show a notification (assuming the user has granted permission) that will take the user back to your web app to continue working.
Because this feature involves running code in the background, with the browser open but the web app potentially closed, there are limits imposed by the browser on how often the code will run. You can't increase the frequency of the retry attempts.
But you can definitely implement retry logic outside of the context of the service worker and background sync, by running code at the frequency you desire from within the context of your web app itself. But in that scenario, the retries will cease as soon as the user closes your web app.
I have a web application that needs to refresh some values often because the changes have to be available almost in real time. To do this, I run via ajax a refresh.php routine every 15 seconds, which returns the updated information. Time that increases if there is no user activity.
I thought about the possibility of creating a service-worker in the browser (since I already use it for pwa too), and in it create a web-socket, and then only when there is an update on the server, create a socket for the ip's of the users that are logged in (and saved in a db), just to send to the user's browser that there is an update, then the web-socket triggers the javascript routine that connects to the server and does the update.
I do not know if it would be possible to create the socket just to inform that there is an update, because in this case, I do not want to leave the socket open, creating the connection only when there is an update of the information, which should happen to several users.
Has anyone ever needed or done anything like this, or would you have any other ideas?
Hello I am developing an auction app like tophatter.com. I want to implement an application that has background process in it. I want this process to run forever until I stop it
http://eoction.com thatss our current site. The problem on our site when we refresh the page the auction also restart. We need something like a continuous process like tophatter.com if you refresh the page it will load the updated auction process.
I found this great service called pubnub. I am thinking we need a background process for this? This will process the auction on the pubnub blocks and then when we visit the site we will just need to query on its updated process?
Does pubnub support something like this?
PubNub Web Page Best Practices
When user refreshes your web app page or navigates to another page there are things you need to consider as a web app developer no matter what technologies you may be using. I will address, at a high level, the things you need to do when PubNub is integrated into your web page.
Restore Parameter
Whether the user interrupts your connection to PubNub or it is a network failure, you will want PubNub to reconnect and continue where it left off as much as possible. The PubNub JavaScript SDK has a initialization parameter called restore that when set to true, will reconnect to PubNub and get missed messages after the connection is dropped and reestablished.
var pubnub = new PubNub({
subscribeKey: "mySubscribeKey",
publishKey: "myPublishKey",
ssl: true,
uuid: getUUID();
restore: true
});
Reuse UUID
It is important to reuse the same UUID for each end user as this will allow PubNub to identify that user uniquely when it comes to Presence so that it doesn't produce new join events for the same end user. The PubNub JavaScript SDK actually generates a UUID and stores it in localStrorage and reuses it by default but very likely you have your own UUID that you would like to use for each of your end users.
Last Message Received Timetoken
If the network disruption is brief as is the case with a page refresh or page navigation, then missed messages are retrieved when restore:true is implemented in the init as stated above. But when the user is offline for more than say 5 minutes, you may want to retrieve missed messages on one or more channels. The best way to do this is to keep track of the timetoken of the last received message by storing it in localStorage every time a message is received via subscribe callback. When the user comes back online and it is has been more than 5 minutes since they were last online, call history using this last received message timetoken on each channel that you need to get missed message from.
Subscribe to Channels
Finally, you'll want to make sure that the user is subscribed to the channel they expect to be based on what their state prior to the connection disruption. If it is a page refresh, you likely just want to resubscribe them to the same list of channels. To do this, you just need to keep a list of channels they are currently subscribed to, once again, in localStorage. If the user navigates to a new page and this causes a full page reload (modern web apps should not require this, but...) then you may want to unsubscribe from some channel(s) and subscribe to new channel(s), it just depends on what that page navigation means to your app. Modern web app frameworks do not require full page reload for page navigation since the web app acts more like a desktop app than older web apps. And again, if the the user was offline for quite some time (more than 5 minutes) then it may not make sense to subscribe them to the same channels that they were subscribed to before. Really depends on your use case.
And by the way, Tophatter uses PubNub ;) but all of the above are generic best practice guidelines and recommendations and is not referencing any one app in particular.
EDIT: To address you question specifically, as pointed out in comments below...
You can't implement long-running process in PubNub BLOCKS (not currently, anyways), so you will need a server process for this. When the user refreshes the page, you just need to hit your server for current state. If using PubNub to keep this progress bar updated in realtime, you just subscribe to that channel that is sending the state of that progress bar and update your client. Using the same best practices I provided above are still necessary.
I maintain a system built with Ruby on Rails. The client has asked me to prevent the system from working when a specific user has no internet connection.
How would you do it?
I need to check if a specific computer has internet connection!
For instance if my pc or your pc or my mother's pc has no internet connection!
This has nothing to do with Ruby on Rails.
Is this user accessing a site that's on a local network but no outside internet access? If so you can have a before_filter or some kind of method on your homepage that tries to ping google.com or some other site outside of the LAN to check for internet.
Use Offline.js
Add offline.min.js file in your vendor/assets/javascripts
Require it in your app/assets/javascripts/application.js as //= require offline.min
Add the following code in the same application.js file
$(document).ready(function() {
Offline.check();
Offline.on('up', function() {
$('a.btn').removeClass('disabled');
});
Offline.on('down', function() {
$('a.btn').addClass('disabled');
});
});
This is in relevance to my code where I just disable all buttons when the connection goes off.
The default behaviour of Offline.js adds a overlay with a please wait message until the internet connection comes back on.
I prefer to handle it this way as it give better user experience. Disabling buttons is a subtle way of preventing a user from working.
So just to clarify, your Rails application exists for users to send food delivery requests to one specific user -- the shop preparing and sending that food out, presumably -- and you want users to be unable to create new delivery requests when the shop/owner isn't currently online?
The simplest way to implement this would be to have an Admin Dashboard area where the owner can click a button to 'open the shop' and allow new orders. The worry, then, is about the shop's connection going offline, resulting in customers whose order are never received. To get around that, you can have each customer order start in an 'unconfirmed' state; when a new order is submitted, the owner is notified, and he can click a button to confirm it, letting the user know that yes, their order has been seen and is being made (and their credit card can be charged then, if you have online payment). This is probably the most reliable solution because what you really want is confirmation that a human has acknowledged the order.
If you do want to tie it directly to online status, then you can have the Admin Dashboard page regularly check that it's being viewed. You could accomplish this with a websockets connection, see Action Cable introduced in Rails 5. The Admin Dashboard page opens a websocket connection upon login; the new-connection event sets accepting_orders = true. The websocket disconnect event sets accepting_orders = false, which will happen soon after their connection is dropped (make sure to check the timeout settings). Without websockets, you could have a background HTTP request occurring on an interval; x seconds without receiving that request could cause Rails to stop accepting new orders.
I want to know if it is possible to use javascript/html or php, etc... to create a page that receives continuous updates from a feed that uses PubSubHubbub?
How can I do this?
I am new to this, and any tips would be helpful.
Random suggestion - booth WebHooks and PubSubHubbub look cool. Article:
Webhooks let applications talk to each
other using very simple HTTP. Webhook
enabled applications run (so far) on
app hosting sites in the cloud. What
makes them different is that they
constantly scan for POSTS to a
designated URL. To use the
application, you register your
application with the other webhook
enabled application and provide a
callback URL. You POST data from
your app to the url of the receiving
app, and monitor the callback URL for
its response. Your app then takes the
POST it received and processes it.
Pubsubhubbub (PSHB) is a realtime,
multicasting webhooks enabled publish
and subscribe system. Historically on
the net, most information is received
after it is pulled. For example, we
set up receive intervals for our
email. Our browsers update our RSS
feeds at pre determined intervals. We
repeat the same searches over and
over, just looking to see if there is
anything new. Even when we get alerts
for new email or information, the
alerts are generated by actively
polling the source. PSHB changes that.