UnifiedPush: a decentralized, open-source push notification protocolPosted on 2022-12-18 by UnifiedPush Team
A modern Android smartphone relies on a lot of services, from app stores and calendars to messaging and push notifications. Most of them have open alternatives, but until now, the only option for push notifications was Google’s proprietary service, Firebase Cloud Messaging (FCM). UnifiedPush is a new alternative that allows you to get push notifications without being tied to a single company.
Push notifications are essential to the modern mobile experience because they allow apps to communicate with users in real-time, even when not actively in use. Relying on Google-provided push notifications is a concern for both privacy and independence. The proprietary FCM library cannot be included in F-Droid apps and relies on having Google services. As a result, it is common to see FOSS applications adopt a persistent direct connection between the application and the server as an alternative.
The limitations of direct app-server connections
While it is technically possible for each application to connect to its own server and receive notifications directly, there are several reasons why this approach may not be practical or effective.
Establishing and maintaining a direct connection between an app and a server can be resource-intensive, which can strain the device’s battery, CPU, and network resources.
- To minimize resource load, the operating system (OS) tries to suspend applications that are not actively in use. However, if each app actively maintains a server connection, the OS cannot suspend them.
- Multiple apps pinging their own servers at variable intervals can prevent the device from going into a low-power sleep mode, which can drain the device’s battery faster.
- Giving one special app the ability to make priority connections minimizes these problems and allows for the OS to efficiently suspend other applications and go to sleep, saving resources and reducing battery consumption.
- As a developer, managing background services and optimizing connections can be complex and time-consuming. By using a push notification service, you can offload this responsibility to a dedicated app, allowing you to focus on other aspects of your app.
How do I start with UnifiedPush, as a user?
Applications that support UnifiedPush can receive notifications via a dedicated UnifiedPush application that maintains a single server connection to receive all notifications. We call this “UnifiedPush application” a distributor; it distributes push notifications to other apps on the device. You can choose which distributor you want to use, self-host the server part, or even create your own. For more information on distributors, check out the full list.
To use UnifiedPush on an application that supports it, you have to install and configure your distributor. You can use UP-Example as a simple test app.
All distributors are compatible with all apps
TL;DR on Android
The easiest way to set UnifiedPush up with an application that supports it is to:
- Install the ntfy Android application; this is your distributor
- Open it, and disable battery optimization for it
- Turn on UnifiedPush in the application; it will detect ntfy automatically. (This step depends on the app’s UX)
When there are multiple distributors available (yes, I know I have too many :P), you can pick between them. When there’s just one, it is automatically selected.
How to add UnifiedPush support to my app, as a developer?
To add UnifiedPush support to your application, you first need to ensure that your server is UnifiedPush compatible: it must be able to send notifications to different endpoints, which are URLs pointing to various servers used by users. If your application uses a gateway to work with Google push notifications, modifying the gateway can make it compatible with UnifiedPush.
On the mobile app side, once the user enables UnifiedPush, you have to check for installed distributors on the user’s device. The app should then prompt the user to select the distributor they want to use. Afterward, you can register with it.
The selected distributor will then send a new endpoint, which the application should forward to its server. Then, the app prepares to receive data sent to that endpoint by registering an Android BroadcastReceiver. This BroadcastReceiver handles the messages coming from your server (often a ping to fetch the notifications).
It is important to register the application with the selected distributor every time the application starts, in case they get out of sync. If the application receives the same endpoint again, it does not need to re-register it.
Most of this is handled by the UnifiedPush library. You can find more detailed instructions on our documentation website.
If you need help with implementing UnifiedPush in your app, we are happy to answer any questions you have on our Matrix chat.
Note: This blog post focuses on Android; instructions to add UnifiedPush support on a Linux application can be found on our website.
How does UnifiedPush work under the hood?
At its core, UnifiedPush is a specification. That specification is split into two halves:
- On the device (client) side, it defines an Application Programming Interface (API) to allow any end-user application (ex. your messaging app) to communicate with any distributor application (ntfy, NextPush, etc.)
- On the server side, the API describes how the application server (Matrix homeserver, Mastodon instance, etc.) sends messages to the push server (ntfy server, Nextcloud server, etc.).
Our client libraries and the reference proxies assist in implementing both sides of the specification, respectively.
To obtain a UnifiedPush endpoint (capability URL to send notifications to), the end-user application registers with the UnifiedPush distributor, which maintains a constant connection with the push server. Upon registration, the distributor provides the application with a unique URL pointing to the push server. This endpoint URL is then transmitted by the application client to the application server.
When the application server needs to send a push message to the end-user application, it sends the message to the push server with a simple HTTP POST request. The push server then forwards the push message to the distributor, which delivers it to the end-user application.
One key feature of UnifiedPush is that the communication between the push server and the distributor is not specified. This means that a variety of technologies can be employed, such as WebSockets, Server-Sent Events, XMPP, raw TCP, or even SMS, whatever works best for the user.
The distributor uses platform-specific IPC mechanisms, such as Broadcast Intents on Android or D-Bus on Linux, to wake the app and allow it to handle the push message. The app can then process the data and decide whether to show a notification based on the content. It is important to note that UnifiedPush does not handle the display of user-visible notifications; it only delivers data to the app. Consequently, apps can support notification features in various platforms without involvement from UnifiedPush or the server.
In cases where the application server does not natively support UnifiedPush, a Push Gateway can convert application-specific notifications to the UnifiedPush server protocol. Some popular Push Gateways, such as the one for Matrix, are integrated directly into push servers for self-hosting convenience. In addition, Rewrite Proxies are used in rare cases where the push server does not support UnifiedPush, such as the FCM distributor sending UnifiedPush-over-FCM.
Push Provider = Push Server
Compatibility between UnifiedPush and WebPush
Now, you might be looking at the elephant in the room: WebPush (RFC8030). WebPush is the open standard that browsers use for their push notifications. And the good news is that UnifiedPush is WebPush compatible … mostly.
Basically, application servers that support WebPush but do not need its advanced features and do not restrict push to only popular WebPush servers (those from browser vendors) should work without problems with UnifiedPush providers. We are working on solutions to ensure better and more stable WebPush support.
- The more apps that adopt UnifiedPush, the more useful it becomes. Currently, UnifiedPush is supported by many Matrix and Mastodon apps. We are also working on getting open-source versions of popular apps such as Telegram and Signal to support UnifiedPush.
- Improving WebPush support will also help to increase the number of apps that can use UnifiedPush. We are working towards better WebPush compatibility with UnifiedPush.
- What about built-in distributors in custom Android ROMs like Lineage OS or /e/OS (murena)? Their support could hugely accelerate UnifiedPush-support in the De-Googled community.
- Linux platforms can also benefit from UnifiedPush. Improving the Linux specification and increasing its adoption will help improve battery life and reactivity.
- As UnifiedPush is very flexible, some platforms could achieve even greater efficiency gains by using low-power hardware for the distributor: keeping it on the modem or a low-power core while the phone is asleep.
At the end of the day, if you use a Matrix or Mastodon app or one of the other supported apps on Android, there’s a good chance that you can use UnifiedPush to get your push notifications without relying on Google. You can start using UnifiedPush today by just installing ntfy or choosing another distributor.
If you are an app developer interested in your app receiving push notifications when installed from F-Droid and allowing your users to have independent, self-hosted infrastructure, check out UnifiedPush and feel free to talk to us if you have any questions!