Problems with Open-Source Downloads read https://www.qt.io/blog/problem-with-open-source-downloads and https://forum.qt.io/post/638946

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 ^^


  • Moderators

    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?


  • Qt Champions 2020

    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.


  • Qt Champions 2020

    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) ?


  • Qt Champions 2020

    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"
    

  • Qt Champions 2020

    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


  • Qt Champions 2020

    @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);
    
        }
    

  • Qt Champions 2020

    @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 ...


  • Qt Champions 2020

    @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:

    1_1537282114782_Screenshot (13).png

    2_1537282114782_Screenshot (14).png

    0_1537282114780_Screenshot (12).png


  • Lifetime Qt Champion

    @Robin-Hood Did you add include/lib locations for qtcloudmessaging in your pro file?



  • @jsulm

    I do not know. Where would I have to add that and how would that look exactly?


  • Lifetime Qt Champion

    @Robin-Hood Take a look at "Linking your application against the shared library" chapter in https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application



  • @jsulm
    I do not see any libs I could add. I have done it as it says in the instructions under point 6.
    Here is the link to the instructions: QtCloudMessaging
    So I wrote the code to several pro files:
    QT + = cloud messaging
    QT + = cloudmessagingfirebase

    Before that, I added the code in my qmake scribt:
    "CONFIG + = firebase",
    as I the instructions under point 1 stands.
    If you scroll something up, you can see it in the first picture.


  • Lifetime Qt Champion

    @Robin-Hood said in Push Notifications in QT:

    QT + = cloud messaging

    it should be

    QT + = cloudmessaging
    

    Shouldn't you do the include like this

    #include <QtCloudMessaging>
    

    ?



  • @jsulm

    Yes, I was just prescribed. That's what I wrote in the code. I just downloaded the package from Githup and followed the instructions ...



  • Hello,

    I would like to integrate the existing Qt project QtFirebase Example in another Qt project. I thought about a solution via libs (libaries). When it exists a simple method, for example with libs or other, I'm grateful for comments. Otherwise I know that you can subdivide via subdir, but I would need a step by step statement.

    To clarify again, my point is to include push notifications in an existing Qt project. I've done the QtFirebase Example and I can get push notifications. Now I would like to integrate this functionality into another project. As mentioned earlier, it would be best if I clicked "Add to Library" within another project and the push notification feature is added.

    Surely there must be a possibility, I am convinced of that. Request for feedback.


Log in to reply