Push Notifications in QT
-
Hello,
I would like to receive Push Notifications on my QT app. I've already tried to send and receive Push Notifications with OneSignal, but they do not offer a setup for QT. Then I found out that V-Play provides a plugin for Push Notifications about OneSignal. Stupid is that the plugin seems to be paid and costs $ 49 per month.Can I only receive Push Notifications from OneSignal to my QT app via V-Play?
If this is true or nobody knows more, does anyone know how to send push notifications and receive them on my QT App?
Oh, it would be desirable for a free solution ^^
-
hi @Robin-Hood
theres a pushnotification example in the docs
http://doc.qt.io/qt-5/qtandroidextras-notification-example.html
works only for android, as it is an example for inclusion of native functions.
-
Thank you first.
It would be enough for Android. Can I send and receive push notifications with this example, or how does it work? So without OneSignal, did I understand that correctly? -
You can use the C++ Firebase SDK. Also, Qt has an own module qtcloudmessaging, but you should compile it himself. Anyway, you can look how it work (from that code) and to implement it yourself by analogy.
PS: AFAIK, the firebase works only with mobile OS (iOS, Android), also it provides an Windows/Linux/OSX support as a beta (but I did not tried it).
-
Is it possible to receive push messages with this approach?
How can I figure out the device token?I have already a server which sends push notification. So I just need an app which is able to receive the messages.
-
Is it possible to receive push messages with this approach?
Yes.
How can I figure out the device token?
When the device's application starts, it automatically got a registration token. And you can send this token to your server, to use this token for push notifications.
-
Ok, does this apply to both applications you have proposed? (so for qtcloudmessaging too) ?
-
What is both applications? You can use, e.g. the same qtcloudmessaging on a device side to send and receive the push messages, and on a server side to send the push messages (if to I see from a source code).
PS: I never used the qtcloudmessaging, I just looked on that source code as a basis to implement an own code.
PS: Also there are and another Qt Firebase project.
-
Hello,
I'm just trying to run my app on my phone. It can be translated, but running always displays the same error message. I have linked my project with "firebase_sdk_cpp". I can translate and run other projects with the same Android device. The message is, that it could´t find the path "C:/Users/Robin/QtProjects/build-PushApp-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_11_1_for_Android_armv7-Debug/android-build//build/outputs/apk/android-build-debug.apk" but it creates the path yet itself. I use QT Creater 4.6.2.Here is the error message:
Running command "C:/Users/Robin/AppData/Local/Android/Sdk/platform-tools/adb.exe -s ce10160a4d4faf0b04 install -r C:/Users/Robin/QtProjects/build-PushApp-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_11_1_for_Android_armv7-Debug/android-build//build/outputs/apk/android-build-debug.apk" adb: failed to stat C:/Users/Robin/QtProjects/build-PushApp-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_11_1_for_Android_armv7-Debug/android-build//build/outputs/apk/android-build-debug.apk: No such file or directory Warning: QML import could not be resolved in any of the import paths: QtQuick.Extras.Private.CppUtils Warning: QML import could not be resolved in any of the import paths: QtQuick.Extras.Private.CppUtils Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.impl Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.Fusion.impl Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.Imagine.impl Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.Material.impl Warning: QML import could not be resolved in any of the import paths: QtQuick.Controls.Universal.impl Installing to device failed! 11:34:23: Der Prozess "C:/Qt/Qt5.11.1/5.11.1/android_armv7/bin/androiddeployqt.exe" wurde mit dem Rückgabewert 16 beendet. 11:34:23: Die für das Debuggen erforderlichen Dateien werden installiert. 11:34:23: Paket-Deployment: Führe Kommando "C:/Users/Robin/AppData/Local/Android/Sdk/platform-tools/adb.exe -s ce10160a4d4faf0b04 pull /system/bin/app_process32 C:/Users/Robin/QtProjects/build-PushApp-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_11_1_for_Android_armv7-Debug/app_process" aus. 11:34:23: Paket-Deployment: Führe Kommando "C:/Users/Robin/AppData/Local/Android/Sdk/platform-tools/adb.exe -s ce10160a4d4faf0b04 pull /system/bin/linker C:/Users/Robin/QtProjects/build-PushApp-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_11_1_for_Android_armv7-Debug/linker" aus. 11:34:23: Paket-Deployment: Führe Kommando "C:/Users/Robin/AppData/Local/Android/Sdk/platform-tools/adb.exe -s ce10160a4d4faf0b04 pull /system/lib/libc.so C:/Users/Robin/QtProjects/build-PushApp-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_11_1_for_Android_armv7-Debug/libc.so" aus. Fehler beim Erstellen/Deployment des Projekts PushApp (Kit: Android für armeabi-v7a (GCC 4.9, Qt 5.11.1 for Android armv7)) Bei der Ausführung von Schritt "Deployment auf Android-Gerät"
-
It is know issue QTBUG-69755. Please search it yourself.
-
Ok that worked. Thank you.
Now I can receive messages in my app that I previously sent in https://console.firebase.google.com. If my app is in the foreground, the message will be forwarded directly to the app. But if it is in the background, or even completely closed, the message is ONLY displayed at the top of the message bar of my mobile phone. This is a problem, because I want to display the messages in the app even if they were in the background before.
So the app knows, if I press the message at the top of the message bar, but the App does not know the message itself.
Is it not possible to give the received message to the function as soon as I press on it?PS: I work with QT Firebase
-
@Robin-Hood said in Push Notifications in QT:
So the app knows, if I press the message at the top of the message bar, but the App does not know the message itself.
Because when the app is in background, it is stopped. And then any received messages will be accumulated on a "message bar" of your phone. These messages even will be appeared when your application is not started at all.
But when you will click on any received message (from the message bar), then your application will be started and will receive this 'clicked' message.
-
Yes I understand. When my application is closed, the messages are only displayed in the message bar. And when I press the message, my application starts, but it does not receive the message itself. What can I do to see the message in my application as well?
If I receive a message while the application is in the background and I click on it, then "void MessageListener :: OnMessage (const messaging :: Message & message)" will be started, but "message.notification" will be false. Only "message.notification_opened" is true, whereupon the string "launchnotification" is passed, but that is useless.
void MessageListener::OnMessage(const messaging::Message &message) { // When messages are received by the server, they are placed into an // internal queue, waiting to be consumed. When ProcessMessages is called, // this OnMessage function is called once for each queued message. QVariantMap data; if (message.notification) { if (!message.notification->title.empty()) { const QString key = QStringLiteral("nTitle"); const QString value = QString::fromStdString(message.notification->title.c_str()); data.insert(key, value); } if (!message.notification->body.empty()) { const QString key = QStringLiteral("nBody"); const QString value = QString::fromStdString(message.notification->body.c_str()); data.insert(key, value); } if (!message.notification->icon.empty()) { const QString key = QStringLiteral("nIcon"); const QString value = QString::fromStdString(message.notification->icon.c_str()); data.insert(key, value); } if (!message.notification->tag.empty()) { const QString key = QStringLiteral("nTag"); const QString value = QString::fromStdString(message.notification->tag.c_str()); data.insert(key, value); } if (!message.notification->color.empty()) { const QString key = QStringLiteral("nColor"); const QString value = QString::fromStdString(message.notification->color.c_str()); data.insert(key, value); } if (!message.notification->sound.empty()) { const QString key = QStringLiteral("nSound"); const QString value = QString::fromStdString(message.notification->sound.c_str()); data.insert(key, value); } if (!message.notification->click_action.empty()) { const QString key = QStringLiteral("nClickAction"); const QString value = QString::fromStdString(message.notification->click_action.c_str()); data.insert(key, value); } } if (message.notification_opened) { const QString key = QStringLiteral("launchnotification"); data.insert(key, true); } for (const auto& field : message.data) { const QString key = QString::fromStdString(field.first); const QString value = QString::fromStdString(field.second); data.insert(key, value); } setData(data); }
Although it says, "As a workaround, we override onNewIntent so that the intent is passed to the C ++ Library Service, which forwards the data to the native C ++ messaging library."
...?/** * Workaround for when a message is sent containing both a Data and Notification payload. * * When the app is in the foreground all data payloads are sent to the method * `::firebase::messaging::Listener::OnMessage`. However, when the app is in the background, if a * message with both a data and notification payload is receieved the data payload is stored on * the notification Intent. NativeActivity does not provide native callbacks for onNewIntent, so * it cannot route the data payload that is stored in the Intent to the C++ function OnMessage. As * a workaround, we override onNewIntent so that it forwards the intent to the C++ library's * service which in turn forwards the data to the native C++ messaging library. */ @Override protected void onNewIntent(Intent intent) { // If we do not have a 'from' field this intent was not a message and should not be handled. It // probably means this intent was fired by tapping on the app icon. // TODO Bundle extras = intent.getExtras(); String from = extras.getString(EXTRA_FROM); String messageId = extras.getString(EXTRA_MESSAGE_ID_KEY); if (messageId == null) { messageId = extras.getString(EXTRA_MESSAGE_ID_KEY_SERVER); } if (from != null && messageId != null) { Intent message = new Intent(this, MessageForwardingService.class); message.setAction(MessageForwardingService.ACTION_REMOTE_INTENT); message.putExtras(intent); startService(message); } setIntent(intent); }
-
@Robin-Hood said in Push Notifications in QT:
but it does not receive the message itself. What can I do to see the message in my application as well?
Hmm. For me when the OnMessage is called (when I click on the message in messages bar) the ::firebase::messaging::Message contains all required fields like (title, body and so on).
Do you have an 'google-services.json' and appropriate content in 'build.gradle' files?
-
Yes. So I downloaded google-services.json from Firebase and 'build.gradle' from GitHub from QtFirebase.
mmh send your content of 'build.gradle' here. Maybe that brings something ...
-
@Robin-Hood said in Push Notifications in QT:
mmh send your content of 'build.gradle' here.
buildscript { repositories { jcenter() google() maven { url 'https://maven.google.com' } } dependencies { classpath 'com.android.tools.build:gradle:3.1.3' classpath 'com.google.gms:google-services:4.0.2' } } allprojects { repositories { jcenter() google() maven { url 'https://maven.google.com' } flatDir { dirs "$System.env.GOOGLE_FIREBASE_SDK" + "/libs/android" } } } apply plugin: 'com.android.application' apply plugin: 'com.google.gms.google-services' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.google.android.gms:play-services-base:15.0.1' implementation 'com.google.firebase:firebase-core:16.0.1' implementation 'com.google.firebase:firebase-messaging:17.1.0' implementation 'com.google.firebase.messaging.cpp:firebase_messaging_cpp@aar' } android { /******************************************************* * The following variables: * - androidBuildToolsVersion, * - androidCompileSdkVersion * - qt5AndroidDir - holds the path to qt android files * needed to build any Qt application * on Android. * * are defined in gradle.properties file. This file is * updated by QtCreator and androiddeployqt tools. * Changing them manually might break the compilation! *******************************************************/ compileSdkVersion androidCompileSdkVersion.toInteger() buildToolsVersion androidBuildToolsVersion sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] res.srcDirs = [qt5AndroidDir + '/res', 'res'] resources.srcDirs = ['src'] renderscript.srcDirs = ['src'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] } } lintOptions { abortOnError false } applicationVariants.all { variant -> variant.outputs.all { outputFileName = "../" + outputFileName } } }
-
Unfortunately that did not work. I am now trying to continue my project using qtcloudmessaging
In the instructions it says under point 5:
"First install QtCloudMessaging from the command line:
qmake "CONFIG + = Embedded-Kaltiot Firebase" make make install "I do not know how do I install it from the command line. ... I use windows 10
-
So I think I found where it is to install QtCloudMessaging. You can see it in the first picture. I hope that was right.
But the compiler is still nagging :/I have copy the compiler report:
C:\Users\Robin\QtProjects\build-qtcloudmessaging-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_11_1_for_Android_armv7-Debug\lib\libQt5CloudMessaging.so konnte nicht gefunden werden move libQt5CloudMessaging.so ..\..\lib\ process_begin: CreateProcess(NULL, move libQt5CloudMessaging.so "..\..\lib ", ...) failed. make (e=2): Das System kann die angegebene Datei nicht finden. make[2]: [..\..\lib\libQt5CloudMessaging.so] Error 2 (ignored) … C:\Users\Robin\QtProjects\qtcloudmessaging\src\cloudmessagingembeddedkaltiot\qcloudmessagingembeddedkaltiotclient.cpp In file included from C:\Users\Robin\QtProjects\qtcloudmessaging\src\cloudmessagingembeddedkaltiot\qcloudmessagingembeddedkaltiotclient.cpp:29:0: C:\Users\Robin\QtProjects\qtcloudmessaging\src\cloudmessagingembeddedkaltiot\qcloudmessagingembeddedkaltiotclient.h:32:45: fatal error: QtCloudMessaging/QtCloudMessaging: No such file or directory #include <QtCloudMessaging/QtCloudMessaging> ^ compilation terminated. make[2]: *** [.obj\qcloudmessagingembeddedkaltiotclient.obj] Error 1 make[1]: *** [sub-cloudmessagingembeddedkaltiot-make_first] Error 2 make[2]: Leaving directory `C:/Users/Robin/QtProjects/build-qtcloudmessaging-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_11_1_for_Android_armv7-Debug/src/cloudmessagingembeddedkaltiot' make[1]: Leaving directory `C:/Users/Robin/QtProjects/build-qtcloudmessaging-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_11_1_for_Android_armv7-Debug/src' make: *** [sub-src-make_first] Error 2 16:12:54: Der Prozess "C:\Users\Robin\android-ndk-r17b\prebuilt\windows-x86_64\bin\make.exe" wurde mit dem Rückgabewert 2 beendet. Fehler beim Erstellen/Deployment des Projekts qtcloudmessaging (Kit: Android für armeabi-v7a (GCC 4.9, Qt 5.11.1 for Android armv7)) Bei der Ausführung von Schritt "Make"
If you want to help me, I think it would be easiest if you look at the manual -> qtcloudmessaging
:)Here are three more pictures. Maybe they will help you with troubleshooting:
-
@Robin-Hood Did you add include/lib locations for qtcloudmessaging in your pro file?