I am coding a vue.js app using web pushes with Firebase Cloud Messaging and I wondered if it was possible to send a web push to a user and in case the user was offline, to somehow store it for later display when the user opens the app again. Is there a principled approach to this problem, i.e. managing web pushes when the end user is offline?
The reason I am asking this is that, so far, all the web push notifications I've committed to FCM server with tokens of offline clients (i.e. desktop browsers) went into oblivion. To be sure, FCM didn't try pushing the notification again when the clients went back online.
For this reason I am considering coding a self-made dispatcher to manage web push for offline clients, but I need to make sure my efforts are worth it.
updated: I am now able to display notifications sent to an offline client after coming back online using appropriate time_to_live values. However, only the latest notification is displayed. How is there any specific reason why?
FCM's default behavior is exactly like that. From the docs:
If the device is not connected to FCM, the message is stored until a connection is established (again respecting the collapse key rules). When a connection is established, FCM delivers all pending messages to the device.
Related
I host a PWA website and I am trying to integrate push notifications to my users who may have the website open in a browser tab even if their phones are inactive. You notoriously can't send Push notifications to iPhones without using Apple Push Notifications service (APNs).
Seeing as the point of firebase cloud messaging (FCM) is to outsource the message handlers, I kinda assumed it would support sending push notifications to iPhones somehow via APNs, but the information here suggests you still can't do this from the web.
https://firebase.google.com/docs/cloud-messaging/js/client
Safari and iPhones don't support Push API.
According to this answer: https://stackoverflow.com/a/64576541/2116253
Option #2 may be possible if you know the device ID token, which is apparently very hard to get and perhaps not possible anymore because Apple are trying to make it harder to obtain due to security concerns.
I think the actual sending via APNs from server side is quite easy, the problem comes with the initial setup/registration and actually granting permissions that allow notifications to arrive.
So, in short, I don't mind registering my website with Apple, agreeing to terms and obtaining keys for the purpose of interfacing with APNs, but I don't want to make and distribute a whole native iOS app just to send notifications to devices about my website.
Does anybody know the correct way to achieve this in 2022 ?
Update: Google Bug Report Description
(as suggested by google dev advocate in comments on answer 1, filed a bug report; updating the content here since it more succinctly and precisely describes the problem)
I do not need or want to show any notifications to my user. And many users are not willing to give notifications permission because they assume they will start seeing notifications.
But I wish to push data to my web page from the server. The web page is active and in the foreground. This is the classic use case that Web Sockets were designed for.
I understand that I could write my own web socket server and somehow try to scale it, or go to some other third-party for an outsourced scalable web socket push solution.
But, isn't this is a very common "sub-use-case" of the messaging that Firebase Messaging is targeted towards? Therefore shouldn't Google support this use case? I can't see any fundamental technical show-stoppers, but since Google is so smart, please do enlighten me if I am missing something on why this cannot or should not be done.
Original StackOverflow Question Text:
I don't need background notifications or service workers. All I want is to send data to the web page when it is currently loaded and in the foreground.
Websockets do not need any permission but they need a websocket server and maintenance. It is difficult or expensive to scale it.
Firebase solves the problem fundamentally but I don't see why it must require a user to give notifications permission even though I only want to push data when the page is loaded; not in the background.
The problem is that Firebase Messaging is only using 1 method to deliver notifications. That is the Push API specification spec, and that specification (wrongly and unfortunately) does not allow a service worker to receive messages without the user allowing an unrelated permission to show notifications.
The fix would be for the Firebase Messaging team to provide a different way to deliver messages to active web pages -- long polling, or websockets.
But it would be extra work for them, and may be not enough people are requesting it.
It's to protect the user's preferences about what your app is allowed to do. The way push messaging works on browsers is by using a service worker. Even though you say you don't need a service worker, you are actually making using of it when using Firebase Cloud Messaging in your app.
Given that, the prompt is necessary because the browser doesn't know what you intend to do with that push message. If the user doesn't trust your app, they should have the right to limit what it can actually do, especially when they're not using your app. Mobile operating systems (iOS, Android) are the same way.
Update: Google Bug Report Description
(as suggested by google dev advocate in comments on answer 1, filed a bug report; updating the content here since it more succinctly and precisely describes the problem)
I do not need or want to show any notifications to my user. And many users are not willing to give notifications permission because they assume they will start seeing notifications.
But I wish to push data to my web page from the server. The web page is active and in the foreground. This is the classic use case that Web Sockets were designed for.
I understand that I could write my own web socket server and somehow try to scale it, or go to some other third-party for an outsourced scalable web socket push solution.
But, isn't this is a very common "sub-use-case" of the messaging that Firebase Messaging is targeted towards? Therefore shouldn't Google support this use case? I can't see any fundamental technical show-stoppers, but since Google is so smart, please do enlighten me if I am missing something on why this cannot or should not be done.
Original StackOverflow Question Text:
I don't need background notifications or service workers. All I want is to send data to the web page when it is currently loaded and in the foreground.
Websockets do not need any permission but they need a websocket server and maintenance. It is difficult or expensive to scale it.
Firebase solves the problem fundamentally but I don't see why it must require a user to give notifications permission even though I only want to push data when the page is loaded; not in the background.
The problem is that Firebase Messaging is only using 1 method to deliver notifications. That is the Push API specification spec, and that specification (wrongly and unfortunately) does not allow a service worker to receive messages without the user allowing an unrelated permission to show notifications.
The fix would be for the Firebase Messaging team to provide a different way to deliver messages to active web pages -- long polling, or websockets.
But it would be extra work for them, and may be not enough people are requesting it.
It's to protect the user's preferences about what your app is allowed to do. The way push messaging works on browsers is by using a service worker. Even though you say you don't need a service worker, you are actually making using of it when using Firebase Cloud Messaging in your app.
Given that, the prompt is necessary because the browser doesn't know what you intend to do with that push message. If the user doesn't trust your app, they should have the right to limit what it can actually do, especially when they're not using your app. Mobile operating systems (iOS, Android) are the same way.
I am making a website and one of the features is that whenever a contract is nearing its end, the user should be notified about it. So I was looking for a way to notify users and I found out about push notifications.
Now, there are lots of things written about it. I heard a lot about Google Cloud Messaging, Firebase Cloud Messaging and Service Workers.
Now the thing is that my website will probably be on an Intranet. So maybe I won't be able to use GCM/FCM.
But I have a few questions regarding GCM, FCM and Service-Workers:
Why do I need FCM/GCM?
What is the difference between FCM and Service Workers?
Is there a way to push notifications even if the browser is closed?
Because my website is on an Intranet, is there another way to push notifications to the users?
1. Why do I need FCM/GCM?
You may check here the features of FCM.
Notification payload: 4KB, Message payload: 2KB. Note that the notification includes device and app information too.
Stores 100 notification/messages per device if the device is offline.
Stores notification/messages for 30 days if the device is offline, and deleted them all one this period is over and the device is still offline.
FCM supports Android and iOS devices, and even chrome web apps. The notifications are sent to iOS devices in this way: App Server -> FCM -> Apple Push Notification Server (APNs) -> iOS device -> App.
GCM supports 1 million subscribers while FCM do not have this limitation.
Supports programming in C++.
Less requirements for coding.
2. What is the difference between FCM and Service Workers?
Service Worker is a background service that handles network requests. Ideal for dealing with offline situations and background syncs or push notifications. Cannot directly interact with the DOM. Communication must go through the Service Worker’s postMessage method. Service Workers are pretty perfect for creating offline-first web apps. They let you interact with the server when you can (to fetch new data from the server, or push updated info back to the server), so your app can work regardless of your user’s connectivity.
While using FCM, you can notify a client app that new email or other data is available to sync. You can send notification messages to drive user reengagement and retention. For use cases such as instant messaging, a message can transfer a payload of up to 4KB to a client app.
3. Is there a way to push notifications even if the browser is closed?
Check this thread: Notifications while browser is closed
4. Because my website is on an Intranet, is there another way to push notifications to the users?
Unfortunately, I don't see any documentation regarding this.
Hope my answers help you.
I'm trying to understand what I will need to build on my server for Push notifications to work successfully.
My thoughts were:
The phone sends the notify URL to my server
The server stores the information in a Database
A separate process or PHP script will query the database and open continuous looping process for each device. (Each socket will be querying a 3rd party API)
When there is a change detected in the API for that device a push notification will be sent to the device's notify url.
Is this the right method on what needs to be done. Isn't this going to eat up server resources or is it the expected outcome of Push a push notifications server?
I've produced a simple diagram on all this below:
First of all, let's separate the process in the main stages needed for PUSH.
Device subscription.
Send the PUSH
Process the notification on device.
Subscription
For the subscription, your device (more specifically, your App) must call the PUSH api,for enabling PUSH notifications. This call to the push API will give you a URL that uniquely identify the device where your application is installed and running. You should store this URL on your database, the same way you store a user's email, or a user's phone number. No special black magic here. You only use it when you need to send a communication to a user.
Send the PUSH
For the push stuff, the same approach as for email, or SMS messaging here: "One does not simply make an infinite loop and send a message if any change is detected". What you have to do is, just send the PUSH message when your application needs to. So you have the user to which you want to send a message, instead of opening a SMTP connection to send ane mail, just build the PUSH XML Message and call the URL associated with that user. Some things to consider here are:
Network reliability (you need to retry if you can't connect to the server).
Response error code-handling (you don't need to retry if the server tells you that the phone has uninstalled your application, for example).
Scalability. You don't want to send a PUSH message from your PHP code, because you don't know how long it will take for the task to be completed. You have to make this thing asynchronously. So just queue up all the push messages, you can create a separate process (windows service, nodeJS service, cron job, daemon, etc.) to send the PUSH, handle retries and errors and clean the queue.
Process the notification on Device
So now that you are this far, you need to handle the notification on the phone. It depends on the type of PUSH notification that you are sending:
Tile. You will update the image, text and counter of the application tile, if the user has put your application to the start screen. On client side you need nothing to so, as all these parameters are part of your PUSH request.
Toast. This one requires a title, text (limited to some 35 characters more or less) and a relative URL inside of your APP. Your application will be launched (like when you click on a Toast notification from Twitter, for example) using the URI that you specify in the payload. So a bit of data can be already injected here. You may/or may not make a request to your server for new data. It is up to you.
Raw. This one is pretty much silent. Is not seen by the user if your APP is not running. As you might guess, this kind of PUSH is useful to live update your running APP, instead of continuously polling your server, wasting user battery and bandwidth and wasting your server resources. You can send anything (raw bytes or strings) up to the max size of the payload allowed my Microsoft.
If yo have any more questions, don't hesitate to ask.
Bottom line: separate the PUSH sending, make it async, don't you ever forget that...
Your PHP script that continually pings the database for changes...THAT is what will eat up your system resources. Push notifications go hand in hand with Event Driven Programming. This means that ideally, your code shouldn't continuously ping your DB. Rather, when something happens (ie, an "event"), THEN your code does something...like contact your phone via push notification.
Your steps for push notifications are more or less correct, but are incomplete. Step 4: the server contacts the client via the notify url (which you have). Step 5 is that the client then contacts the server to actually pull down the information it needs. That is: The new information is not provided to the client via the notify url. Once the client has its new information, then the program continues as normal (populates a list, downloads skynet, etc.)
Your third step is very wasteful and not practical if your app is installed on more than a few devices.
Instead, each device should be subscribed to types of server updates it cares about. Your server's DB will have a mapping from each type of update you support to the list of notification channel URLs of devices that care about this update type.
When your server detects an update of type X, it would send a notification to all devices subscribed to that type of update.