Student project: Remote push notifications
October 02, 2025 by Bror Wetlesen Vedeld | Comments
Introduction

From left to right: Jakob Mats Emil Wirén, Bror Wetlesen Vedeld, Aksel Matashev
In Spring 2025, three students from NTNU Gjøvik; Jakob Mats Emil Wirén, Aksel Matashev, and Bror Wetlesen Vedeld, carried out a bachelor’s project hosted by the Qt office in Oslo. Our goal was to investigate how native push notification services could be integrated into Qt applications in a cross-platform manner. The resulting experimental library has been named QtPushNotifications, and refers to the implementation that can be found here https://git.qt.io/nils.petter.skalerud/qtpushnotifications. Do note that, at the time of writing, there are no current plans to integrate this functionality into Qt as an official feature, this project was primarily done for research purposes.

End-user applications, especially mobile, have an ever-increasing demand to inform the end-user of updates. These can take the form of being notified of text messages, calls, weather updates, or traffic updates. Several modern platforms have strict restrictions on how applications may connect to the internet while the application is in the background, or the device is asleep. This makes it problematic to use traditional networking methods within an application to listen to events on the web. The solution provided by these platforms comes in the form of remote push notifications.
In the context of this project remote push notifications refer to remote system-level alerts, where a server sends a network notification to a centralized polling loop process owned by the operating system. The platform offers a centralized API which applications may rely on to listen for events. This solution allows the operating system and the end-user to have more control of how applications may connect to the internet, while also allowing the device to improve battery life. Examples of these solutions include Apple Push Notification Services, Firebase Cloud Messaging and Windows Notification Service.
So far, the Qt framework does not have functionalities that allow Qt application developers to leverage this functionality. This student project researches how to integrate this functionality into the Qt framework under a single cross-platform API. The work outlined in QtPushNotifications primarily focuses on the functionality that receives remote push notifications, included in the application code.
We also provide a mock-up of the server component using QHttpServer that communicates with the native services and the QtPushNotifications library running on the client (shown as the App Server in the diagram below). Application developers have to re-implement the server component completely, since QHttpServer is not hardened to be run in public networks. All server components are using REST APIs and our mock-up implementation, in addition to the documentation in the repository, can provide a reference point on how to communicate with the client and the native push notification services from Microsoft and Apple.
Remote push notifications have several benefits from a technical and user-experience perspective. Most notably, they:
- Allows servers to trigger remote state changes in client applications on demand, regardless if the application is parked, running in the background or, on some platforms, terminated.
- Enables workflows normally reserved for foreground or privileged application states to be activated remotely.
The QtPushNotifications library is for client-side applications. It is the application developer’s responsibility to provide a server that sends the notifications.
The overall delivery flow, widely similar for all platforms, is illustrated in the diagram below:
-
Permission Request (Optional) The Qt client application requests permission from the operating system to receive push notifications. This step is optional and should determine whether the app is allowed to register for notifications at all. You can still implement remote push notifications without consent from the end user.
-
Identifier Request
The application contacts the native push service (e.g., APNs, WNS, FCM) to request a unique device or application identifier that can be targeted for notifications. -
Identifier Response
The push service responds with the unique identifier (commonly a token or URI). This identifier represents the specific device/application instance and is used in subsequent message dispatches. -
Identifier Registration
The application forwards this identifier to the app server. The server stores it in a database so it can be used later to send notifications to that device. -
Message Dispatch
When the server wants to send a notification, it uses the stored identifier and sends a message to the corresponding cloud service (e.g. via HTTP request to APNs/WNS/FCM). -
Notification Delivery
The push service delivers the notification to the user’s device. If the application is running, the message is passed directly to it. If the application is terminated, the OS wakes it up (if allowed), or shows a system notification depending on platform capabilities and message type.
The solution currently supports WNS (Windows Notification Services) and APNs (Apple Push Notification services). It was developed using Qt 6.9. During the student project, there was a proof-of-concept prototype using Android and Firebase Cloud Messaging. Due to time constraints during the summer internship, Android support had to be dropped.
Setting up the system still requires some platform-specific configuration for all platforms, including cloud service credentials and application manifests, but the overall structure is intentionally lightweight.
Although some infrastructure components are not bundled by default, the core functionality is in place. Devices can register for remote notifications, and messages can be sent and received through native services using a Qt-friendly signal-based interface. Detailed build instructions and setup guidance are available in the project documentation folder.
Using the API
Registering services
To make remote push notifications work, the application developer must first sign up for accounts with the Push Notification Service that powers their target platform. The repository for QtPushNotifications provides documentation on what information and keys you might need from APNs and WNS.
Adding the API to your application
Remote push notification functionality is tightly coupled to the deployment process and the application manifest on several platforms. As such, it is a requirement in QtPushNotifications that application identifiers are supplied to the application during build time, in particular CMake configuration. These identifiers tie the deployed application binaries to the application you have registered with the Push Notification Service.
Consequently, QtPushNotifications is not to be linked directly using the traditional CMake target_link_libraries, instead QtPushNotifications supplies a CMake function qtpushnotifications_link() that takes care of applying the identifier and the relevant libraries to your application.
qtpushnotifications_link(target
ENABLE_APPLE
APPLE_TEAM_ID "my-apple-team-id"
APPLE_BUNDLE_ID "org.example.myapplication"
IOS_INFO_PLIST "path/to/ios/info.plist"
IOS_ENTITLEMENTS "path/to/ios/entitlements.plist"
MAC_INFO_PLIST "path/to/mac/info.plist"
MAC_ENTITLEMENTS "path/to/mac/entitlements.plist"
ENABLE_WINDOWS
WINDOWS_AZURE_ID "<azure-app-identifier>"
)
Minimal usage examples
How to use the project with C++
Thanks to the CMake function, getting started requires minimal application code to enable push notifications. All functions are invokes through a singleton class, QPushNotificationReceiver. There are two functions you can call to register the application to receive push notifications.
void QPushNotificationReceiver::registerWithService()
This function will connect the service native to the operating system the application is currently running. A signal is emitted on failure and success, the latter containing a device identifier unique to the application and the users device. The application developer has to handle the generated device identifier. You should send the generated identifier to the server infrastructure associated with your application.
The server infrastructure can use these identifiers, in combination with the WNS and APNs to send a payload to the individual applications. Payload in the context of this project refers to the notification body, or message received. This is a QString, that is returned with the pushNotificationReceived signal.
#include <QPushNotificationReceiver>
// Add signal connection for when push notifications are received
QObject::connect(
QPushNotificationReceiver::instance(),
&QPushNotificationReceiver::pushNotificationReceived,
QApplication::instance(),
[](const QString &payload) {
qDebug << "Notification received with body: " << payload;
});
// Add signal connection for when registration is complete
QObject::connect(
QPushNotificationReceiver::instance(),
&QPushNotificationReceiver::registrationComplete,
QApplication::instance(),
[](const QString &token, const QString &serviceIdentifier) {
qDebug << "token generated: " << token
<< " using protocol: " << serviceIdentifier;
});
// Initialize the QPushNotificationReceiver
QPushNotificationReceiver::instance()->registerWithService();
void QPushNotificationReceiver::registerWithService(QUrl, QJsonObject, QNetworkAccessManager*)
This overload performs the registration and sends all available data to the server under the given QUrl. Custom data can be provided with the QJsonObject and the function will amend it with all tokens received by the native push notification services. In practice, this functions sends a POST request via HTTP to the given URL in a format that is documented in the repository. Further we included a reference implementation of the server infrastructure that parses the given data and implements all communication with the native push notification services.
Metadata that might be useful to be added to the QJsonObject in the context of push notifications include:
- deviceModel, osName, osVersion: identifies the device and OS for compatibility and targeting
- appVersion: useful for filtering out clients with known bugs or behavior
- language, timezone: enables localization and scheduling of notifications based on user context
The application developer can also provide a reference to a QNetworkAccessManager that will be used to send the POST request.
The application developer is responsible for setting up a server-side handler to receive device identifiers. The REST API for this is documented in the documentation folder and we can again refer to our mock-up implementation based on QHttpServer that is also included in the repository.
#include <QPushNotificationReceiver>
// Add signal connection for when push notifications are received
QObject::connect(
QPushNotificationReceiver::instance(),
&QPushNotificationReceiver::pushNotificationReceived,
QApplication::instance(),
[](const QString &payload) {
qDebug << "Notification received with body: " << payload;
});
// Initialize the QPushNotificationReceiver
QPushNotificationReceiver::instance()->registerWithService(
QUrl::fromUserInput("127.0.0.1"),
QJsonObject{},
&nam);
Using Push Notifications in QML
To receive push notifications in QML, import the QtPushNotifications module and use the PushNotificationReceiver singleton. This object emits signals when new notifications arrive, which you can handle with QML Connections. The connection still needs to be established in C++.
Minimal example:
import QtQuick
import QtQuick.Controls
import QtPushNotifications
ApplicationWindow {
id: window
visible: true
width: 256
height: 512
Connections {
target: PushNotificationReceiver
function onPushNotificationReceived(notificationBody) {
console.log("Received push notification with body: " + notificationBody);
}
}
}
For more advanced usage, see the official documentation:
Examples
The repository provides two examples. Both of them have a client (end user) and server component, both written in C++ and Qt.
A minimal example can be found in the repository under ... It shows the minimal code that is required to set up push notifications and send simple notifications to your users. The server application, an administrator application, is a QWidgets application that shows the registered devices running your application and allows an administrator to send push notifications to all devices. The client application is a QML application that pops up from the background when a notification is received.
Further, we developed a more intricate example, implementing a chat application where messages are send via push notifications and can as such be received while the application is not active. The chat example was developed to showcase how push notifications can be used in a more practical example. This is a PoC, quite complex to set up in terms of server and multiple clients and is thus not meant to be built by others, except the most stubborn and bravest of developer.
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.10 Now!
Download the latest release here: www.qt.io/download.
Qt 6.10 is now available, with new features and improvements for application developers and device creators.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.
