├── firebaseapi.pro ├── .gitignore ├── main.cpp ├── firebaseexamples.h ├── firebaseexamples.cpp ├── firebase.cpp ├── README.md └── firebase.h /firebaseapi.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # Project created by QtCreator 2015-12-02T10:56:50 3 | #------------------------------------------------- 4 | 5 | QT += core 6 | QT +=network 7 | QT -= gui 8 | 9 | TARGET = firebaseapi 10 | CONFIG += console 11 | CONFIG -= app_bundle 12 | 13 | TEMPLATE = app 14 | 15 | SOURCES += main.cpp \ 16 | firebase.cpp \ 17 | main.cpp \ 18 | firebaseexamples.cpp 19 | 20 | HEADERS += \ 21 | firebase.h \ 22 | firebaseexamples.h 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | qrc_*.cpp 24 | ui_*.h 25 | Makefile* 26 | *build-* 27 | 28 | # QtCreator 29 | 30 | *.autosave 31 | 32 | # QtCtreator Qml 33 | *.qmlproject.user 34 | *.qmlproject.user.* 35 | 36 | # QtCtreator CMake 37 | CMakeLists.txt.user* 38 | buld*/ 39 | 40 | .~* 41 | .~lock.* 42 | *# 43 | thumbs.db -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /*! 7 | * \brief main Text some examples of using Firebase REST API 8 | * 9 | * \param argc Number of arguments 10 | * \param argv 3 user arguments 11 | *
    12 | *
  • Id of example to run
  • 13 | *
  • Firebase Database URL
  • 14 | *
  • Your Firebase Secret
  • 15 | *
16 | * 17 | * \return 18 | */ 19 | int main(int argc, char *argv[]) 20 | { 21 | QCoreApplication a(argc, argv); 22 | 23 | QString strId = "1"; 24 | if (argc >= 2) 25 | strId = argv[1]; 26 | 27 | QString fbUrl; 28 | if (argc >= 3) 29 | fbUrl = argv[2]; 30 | 31 | QString authToken; 32 | if (argc >= 4) 33 | authToken = argv[3]; 34 | 35 | FirebaseExamples *examples = new FirebaseExamples(strId.toInt() 36 | , fbUrl 37 | , authToken); 38 | return a.exec(); 39 | } 40 | -------------------------------------------------------------------------------- /firebaseexamples.h: -------------------------------------------------------------------------------- 1 | #ifndef FIREBASEEXAMPLES_H 2 | #define FIREBASEEXAMPLES_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /*! 12 | * \brief The ActionHandler Examples of using Firebase. 13 | * 14 | * You will probably want to edit this class and run under debug 15 | * to see what happens. 16 | * 17 | * \see Firebase 18 | */ 19 | class FirebaseExamples:public QObject 20 | { 21 | Q_OBJECT 22 | public: 23 | /*! 24 | * \brief ActionHandler 25 | * \param action Id indicating which example you want to run 26 | * \param firebaseURL URL of your Firebase Database 27 | * \param authToken Your Secret. 28 | */ 29 | FirebaseExamples(int action 30 | , const QString& firebaseURL = "" 31 | , const QString& authToken = ""); 32 | 33 | /*! 34 | * \brief patch Example of updating your database with PATCH request. 35 | */ 36 | void patch(); 37 | /*! 38 | * \brief get Example of retrieving part of your database with GET request. 39 | */ 40 | void get(); 41 | /*! 42 | * \brief useToken Example of updating your rules. 43 | * 44 | * Based on example in 45 | * 46 | * Firebase REST API Documentation . 47 | */ 48 | void useToken(); 49 | /*! 50 | * \brief listen Example of listing for database updates. 51 | */ 52 | void listen(); 53 | 54 | public slots: 55 | /*! 56 | * \brief onResponseReady Connect to Firebase replayFinished signal. 57 | * 58 | * \see Firebase::eventResponseReady(QByteArray replyData) 59 | */ 60 | void onResponseReady(QByteArray); 61 | 62 | /*! 63 | * \brief onDataChanged Connect to Firebase eventDataChanged signal 64 | * 65 | * \see Firebase::eventDataChanged(QString changedData) 66 | */ 67 | void onDataChanged(QString); 68 | 69 | private: 70 | QString fbUrl; 71 | QString authToken; 72 | }; 73 | 74 | #endif // FIREBASEEXAMPLES_H 75 | -------------------------------------------------------------------------------- /firebaseexamples.cpp: -------------------------------------------------------------------------------- 1 | #include "firebaseexamples.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | FirebaseExamples::FirebaseExamples(int action 9 | , const QString &firebaseURL 10 | , const QString &authToken) 11 | : fbUrl(firebaseURL), authToken(authToken) 12 | { 13 | switch (action) 14 | { 15 | case 1: 16 | patch(); 17 | break; 18 | case 2: 19 | get(); 20 | break; 21 | case 3: 22 | useToken(); 23 | break; 24 | case 4: 25 | listen(); 26 | break; 27 | }; 28 | 29 | } 30 | 31 | void FirebaseExamples::patch() 32 | { 33 | QJsonObject jsonObj; 34 | jsonObj["user"] = "hii"; 35 | jsonObj["password"] = "password"; 36 | jsonObj["email"] = "email@hi.co.uk"; 37 | QJsonDocument uploadDoc(jsonObj); 38 | QString path="lll/users/fred/"; 39 | Firebase *firebaseSet = new Firebase(fbUrl, path); 40 | firebaseSet->setValue(uploadDoc, "PATCH"); 41 | 42 | connect(firebaseSet,SIGNAL(eventResponseReady(QByteArray)) 43 | ,this,SLOT(onResponseReady(QByteArray))); 44 | } 45 | 46 | 47 | void FirebaseExamples::get() 48 | { 49 | Firebase *firebaseGet=new Firebase(fbUrl, "lll/users/.json"); 50 | qDebug()<<"URL:" << firebaseGet->getPath(); 51 | firebaseGet->getValue(); 52 | 53 | connect(firebaseGet,SIGNAL(eventResponseReady(QByteArray)) 54 | ,this,SLOT(onResponseReady(QByteArray))); 55 | } 56 | 57 | void FirebaseExamples::useToken() 58 | { 59 | QJsonObject jsonRule; 60 | jsonRule[".read"] = true; 61 | QJsonObject jsonRules; 62 | jsonRules["rules"] = jsonRule; 63 | QByteArray ba; 64 | QJsonDocument uploadDoc(jsonRules); 65 | ba = uploadDoc.toJson(QJsonDocument::Compact); 66 | Firebase *firebaseSet = new Firebase(fbUrl, ".settings/rules"); 67 | qDebug()<<"URL:" << firebaseSet->getPath(authToken); 68 | firebaseSet->setValue(uploadDoc, "PUT", authToken); 69 | 70 | connect(firebaseSet,SIGNAL(eventResponseReady(QNetworkReply)) 71 | ,this,SLOT(onResponseReady(QNetworkReply))); 72 | 73 | } 74 | 75 | void FirebaseExamples::listen() 76 | { 77 | Firebase *firebaseGet=new Firebase(fbUrl, "lll/.json"); 78 | firebaseGet->listenEvents(); 79 | connect(firebaseGet,SIGNAL(eventResponseReady(QByteArray)) 80 | ,this,SLOT(onResponseReady(QByteArray))); 81 | connect(firebaseGet,SIGNAL(eventDataChanged(QString)) 82 | ,this,SLOT(onDataChanged(QString))); 83 | } 84 | 85 | void FirebaseExamples::onResponseReady(QByteArray data) 86 | { 87 | qDebug()<<"onResponseReady"; 88 | qDebug()< 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | Firebase::Firebase(const QString &hostName 12 | , const QString &dbPath 13 | , QObject *parent) 14 | : QObject(parent) 15 | { 16 | host = forceEndChar(hostName.trimmed(), '/'); 17 | host = host.append(dbPath.trimmed()); 18 | init(); 19 | } 20 | 21 | void Firebase::init() 22 | { 23 | manager=new QNetworkAccessManager(this); 24 | connect(manager,SIGNAL(finished(QNetworkReply*)) 25 | ,this,SLOT(replyFinished(QNetworkReply*))); 26 | } 27 | 28 | void Firebase::listenEvents(const QString& queryString) 29 | { 30 | open(buildPath(queryString)); 31 | } 32 | 33 | void Firebase::open(const QUrl &url) 34 | { 35 | QNetworkRequest request(url); 36 | request.setRawHeader("Accept", "text/event-stream"); 37 | QNetworkReply *_reply = manager->get(request); 38 | connect(_reply, &QNetworkReply::readyRead, this, &Firebase::eventReadyRead); 39 | connect(_reply, &QNetworkReply::finished, this, &Firebase::eventFinished); 40 | } 41 | 42 | void Firebase::eventFinished() 43 | { 44 | QNetworkReply *reply = qobject_cast(sender()); 45 | if (reply) 46 | { 47 | QUrl redirectUrl = reply->attribute( 48 | QNetworkRequest::RedirectionTargetAttribute).toUrl(); 49 | if (!redirectUrl.isEmpty()) 50 | { 51 | reply->deleteLater(); 52 | open(redirectUrl); 53 | return; 54 | } 55 | reply->deleteLater(); 56 | } 57 | } 58 | 59 | void Firebase::eventReadyRead() 60 | { 61 | QNetworkReply *reply = qobject_cast(sender()); 62 | if(reply) 63 | { 64 | QByteArray line=reply->readLine(); 65 | if(!line.isEmpty()) 66 | { 67 | QByteArray eventName=trimValue(line); 68 | line=reply->readAll(); 69 | if(eventName=="put") 70 | { 71 | QString dataSnapshot(line); 72 | emit eventDataChanged(dataSnapshot); 73 | } 74 | } 75 | } 76 | reply->readAll(); 77 | } 78 | 79 | 80 | void Firebase::setValue(QJsonDocument jsonDoc 81 | , const QString &verb 82 | , const QString& queryString) 83 | { 84 | QString path = buildPath(queryString); 85 | QNetworkRequest request(path); 86 | request.setHeader(QNetworkRequest::ContentTypeHeader, 87 | "application/x-www-form-urlencoded"); 88 | QByteArray jsonBA = jsonDoc.toJson(QJsonDocument::Compact); 89 | 90 | QBuffer *buffer=new QBuffer(); 91 | buffer->open((QBuffer::ReadWrite)); 92 | buffer->write(jsonBA); 93 | buffer->seek(0); 94 | 95 | QByteArray verbBA = verb.toUtf8(); 96 | manager->sendCustomRequest(request, verbBA ,buffer); 97 | buffer->close(); 98 | } 99 | 100 | void Firebase::getValue(const QString& queryString) 101 | { 102 | QNetworkRequest request(buildPath(queryString)); 103 | manager->get(request); 104 | } 105 | 106 | void Firebase::replyFinished(QNetworkReply *reply) 107 | { 108 | emit eventResponseReady(reply->readAll()); 109 | } 110 | 111 | QString Firebase::getPath(const QString &queryString) 112 | { 113 | return buildPath(queryString); 114 | } 115 | 116 | QString Firebase::buildPath(const QString &queryString) 117 | { 118 | QString destination=host; 119 | 120 | const int dotJsonLength = 5; 121 | if (destination.length() <= dotJsonLength 122 | || destination.right(dotJsonLength) != ".json") 123 | destination.append(".json"); 124 | 125 | if (queryString.length() > 0) 126 | destination.append(forceStartChar(queryString,'?')); 127 | 128 | return destination; 129 | } 130 | 131 | QByteArray Firebase::trimValue(const QByteArray &line) const 132 | { 133 | QByteArray value; 134 | int index = line.indexOf(':'); 135 | if (index > 0) 136 | value = line.right(line.size() - index - 1); 137 | return value.trimmed(); 138 | } 139 | 140 | QString Firebase::forceEndChar(const QString &string, char endCh) 141 | { 142 | if (string[string.length()-1] != endCh) 143 | return QString(string).append(endCh); 144 | return string; 145 | } 146 | 147 | QString Firebase::forceStartChar(const QString &string, char startCh) 148 | { 149 | if (string.length() > 0 && string[0] != startCh) 150 | return QString(string).prepend(startCh); 151 | return string; 152 | } 153 | 154 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qt Firebase REST API 2 | 3 | This provides a wrapper around the Firebase REST API for use with Qt Projects. An alternative explanation of this project can be found at [the blog post](http://piersshepperson.co.uk/programming/2017/06/26/firebase-database-rest-api-qt/). 4 | 5 | Details of the Firebase REST API can be found at [here](https://firebase.google.com/docs/reference/rest/database/). 6 | 7 | This project is related to [chlasd's Firebase API](https://github.com/clkasd/qt-firebaseapi) but updated, slimmed and modernised. 8 | 9 | To use, copy the firebase.h and firebase.cpp files into your own projects. Either copy the files form GitHub indivdually, or downlaod the whole project with 10 | 11 | `git clone https://github.com/Sriep/Qt_Firebase_REST_API.git` 12 | 13 | ## Overview 14 | 15 | The API supports three types of commands. Read, write and listen. The steps to perform a request are as follows. 16 | 17 | 1. Create a Firebase object. The constructor takes your Firebase URL and REST endpoint inside your database as parameters. 18 | 2. Call the appropriate Firebase function. setValue, getValue or listenEvents. All three take the query string as an optional parameter. 19 | 3. Create a slot to connect to either of the Firebase signals, eventDataChange and eventResponseReady. Read up here for a refresher on signals and slots. 20 | 4. If necessary handle the response in your slot(s). 21 | 22 | ## Anatomy of API request. 23 | 24 | Each request can be split up into five main blocks of text plus separators. 25 | 26 | - Data. Used for save requests. This has to be in JSON format. 27 | - Firebase URL. The URL of your database, typically “App-Name.firebaseio.com”. 28 | - REST Endpoint. The location in your database we are interacting with. 29 | - Verb. The action to carry out. GET, PUT, PATCH, POST or DELETE. 30 | - Query. Modifications to your request; appears at the end of the URL. 31 | - Separators. “https://”,”/”,”.json” and “?”. splits the other items. 32 | 33 | ### GET Request 34 | 35 | There is no Data for GET requests and the Verb is already known. So a typical GET request might look like the following. 36 | 37 | `https://[PROJECT_ID].firebaseio-demo.com/users/jack/name.json?print=pretty` 38 | 39 | We make this request through the API follows. First, craete our Firebase object that points to `users/jack/name` item in our database. Then we use `getValue` to gert the content. The `print=pretty` query returns data in human readable format. 40 | 41 | ``` 42 | Firebase *fb=new Firebase("[PROJECT_ID].firebaseio-demo.com" 43 | , "users/jack/name"); 44 | fb->getValue("print=pretty"); 45 | ``` 46 | 47 | ### Save Request 48 | 49 | A save request might look like the following in curl format. Note that in this example there is no query. 50 | ``` 51 | curl -X PUT -d ‘{ 52 | “alanisawesome”: { 53 | “name”: “Alan Turing”, 54 | “birthday”: “June 23, 1912” 55 | } 56 | }’ ‘https://docs-examples.firebaseio.com/rest/saving-data/fireblog/users.json‘ 57 | ``` 58 | 59 | To make this call we could proceed as follows. First, we create our JSON data, I personally think its less error prone to use the Qt JSON API functions rather than raw strings for JSON content. Next, we create our Firebase object that points to `rest/saving-data/fireblog/users` item in our database. We can then call `setValue` passing the data in a `QJsonDocument` and entering the Verb “PUT”. There is no query this time so we skip the optional parameter. 60 | 61 | ``` 62 | QJsonObject jsonDetails; 63 | jsonObj["name"] = "Alan Turing"; 64 | jsonObj["birthday"] = "June 23, 1912"; 65 | QJsonObject jsonAlanTuring; 66 | jsonAlanTuring["alanisawesome"] = jsonDetails; 67 | QJsonDocument uploadDoc(jsonAlanTuring); 68 | Firebase *fb = new Firebase(“docs-examples.firebaseio.com“, “rest/saving-data/fireblog/users“); 69 | fb->setValue(uploadDoc, “PUT“); 70 | ``` 71 | 72 | ### Handle response 73 | 74 | Once we have made a request we will normally wish to see the response. Even if it is just to know the request has finished successfully. To do this we handle the `responesReady` signal from the Firebase object. So if we define an `onResponseReasy` function in our class that is using the Firebase object, we can add the following line: 75 | ``` 76 | connect(fb,SIGNAL(eventResponseReady(QByteArray)) 77 | ,this,SLOT(onResponseReady(QByteArray))); 78 | ``` 79 | And create the onResponseReady function to handle it. You can see examples in firebaseexamples.cpp. 80 | ``` 81 | MyFirebaseUsingClass::onResponseReady(QByteArray replyData) 82 | { 83 | // Handel response 84 | } 85 | ``` 86 | Now whenever the Firebase object emits a responseReasy signal, the onResponseReady function will be called with the `QByteArray` parameter will hold any information returned. You can put any code to handle the data and finish the request in here. The `Firebase::onResponseReasy` signal actually chains the `QtNetworkReply::finished` signal which is emitted when the reply has finished processing. The `QByteArry` parameter is the return value from the inherited function `QtNetworkReply::readAll` which reads all the remaining data. 87 | 88 | ### Stream changes to database 89 | 90 | The Firebase REST API allows the streaming of changes to a single location in your Realtime Database, using the EventSource / Server-Sent Events protocol. Detailed at https://firebase.google.com/docs/reference/rest/database/. 91 | 92 | What that means is that you can listen to a location in your database and every time there is a change at that location you are informed. Each time the data at the point you are watching in your Firebase database is changed, the Firebase object sends an `eventDataChanged` signal. The first time the signal is called it returns the initial contents of your database endpoint, further singls indicate subsequent changes. The following code snippet will arrange for the `onDataChanged` function to handle that signal. 93 | ``` 94 | Firebase *firebaseGet=new Firebase(fbUrl, "lll/.json"); 95 | firebaseGet->listenEvents();; 96 | connect(firebaseGet,SIGNAL(eventDataChanged(QString)) 97 | , this,SLOT(onDataChanged(QString))); 98 | ``` 99 | You can then create the onDataChanged function to place your code to handle the database changes. Look at firebaseexamples.cpp for an example of this. 100 | ``` 101 | MyFirebaseUsingClass::onDataChanged(QString databaseUpdate) 102 | { 103 | // Handel response 104 | } 105 | ``` 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /firebase.h: -------------------------------------------------------------------------------- 1 | #ifndef FIREBASE_H 2 | #define FIREBASE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | /*! 15 | * \brief The Firebase class provides access to the Firebase Database REST API 16 | * 17 | * Enter the URL of your database endpoint in the constructor. The Firebase 18 | * object will now interact with that endpoint. You can send read, write and 19 | * listen requests. Results are accessed by handling the eventResponseReady 20 | * and eventDataChanged signals. 21 | * 22 | * For further infomation check out 23 | * 24 | * this blog post. 25 | * 26 | */ 27 | class Firebase : public QObject 28 | { 29 | Q_OBJECT 30 | public: 31 | /*! 32 | * \brief Firebase constructor, sets the REST endpoint. 33 | * 34 | * Creates a Firebase object that knows your Firebase Database URL, and 35 | * the path to the part of your database you wish to interact with. 36 | * The REST endpoint structure is explained int the 37 | * 38 | * Firebase Database REST API . 39 | * 40 | * \param hostName Firebase database URL. This will look something like 41 | * [PROJECT_ID].firebaseio-demo.com/. A '/' will be added to the end if one 42 | * is not already present. Your Firebase Database URL can be found on your 43 | * Firebase console at the top of the 'Database rh-tab/Data top-tab'. This 44 | * can be empty or null if operating on the whole database. 45 | * 46 | * \param dbPath Path in the database to the location of interest. If 47 | * necessary ".json" will be added at the end. 48 | * 49 | * \param parent Assign parent QObject if required. 50 | */ 51 | explicit Firebase(const QString& hostName = "" 52 | , const QString& dbPath = "" 53 | , QObject *parent = 0); 54 | 55 | /*! 56 | * \brief setValue Sends a write request to your Firebase database. 57 | * 58 | * Assumes the REST endpoint has already been defined in the constructor. 59 | * setValue's parameters make up the rest of the request. The format of the 60 | * requests available at 61 | * 62 | * Firebase Database REST API . 63 | * 64 | * If you want to see the response, handle the Firebase::EventResponseReady 65 | * signal. 66 | * 67 | * \see Firebase::EventResponseReady signal. 68 | * 69 | * \param jsonDoc Data in the format of a QJsonDocuemnt. 70 | * 71 | * \param verb Action to perform. Choices include:: PUT, POST, PATCH and DELETE. 72 | * 73 | * \param queryString Query string, a preceding query is added if necessary. 74 | * Query choices include: access_token, shallow, print, callback, format 75 | * and download. 76 | */ 77 | void setValue(QJsonDocument jsonDoc 78 | , const QString& verb = "PATCH" 79 | , const QString &queryString = ""); 80 | 81 | /*! 82 | * \brief getValue Sends a read or "GET" request to your Firebase database. 83 | * 84 | * Assumes the REST endpoint has already been defined in the constructor. 85 | * setValue's parameters make up the rest of the request. The format of the 86 | * requests available at 87 | * 88 | * Firebase Database REST API . 89 | * To see the response, handle the handle the Firebase::EventResponseReady 90 | * signal; the returned data will be in the QByteArray parameter. 91 | * 92 | * \see Firebase::EventResponseReady signal. 93 | * 94 | * \param queryString Query string, a preceding query is added if necessary. 95 | * Query choices include: access_token, shallow, print, callback, format 96 | * and download. 97 | */ 98 | void getValue(const QString& queryString = ""); 99 | 100 | /*! 101 | * \brief listenEvents Use to stream changes from the REST endpoint. 102 | * 103 | * Download changes made to the indicated location in our Firebase database. 104 | * Details at 105 | * Streaming from the REST API. Handle the Firebase::eventDataChanged 106 | * signal to be informed at the moment changes occur. 107 | * 108 | * /see Firebase::eventDataChanged signal. 109 | * 110 | * \param queryString Query string, a preceding query is added if necessary. 111 | * Query choices include: access_token, startAt, print, endAt, orderBy. 112 | */ 113 | void listenEvents(const QString& queryString = ""); 114 | 115 | /*! 116 | * \brief getPath Returns the URL that a request would use. 117 | * 118 | * This is an information only function. It returns the request that would 119 | * be sent if the given query. Useful for debugging. 120 | * 121 | * \param queryString Query string. 122 | * 123 | * \return The request that would be sent if the given query. 124 | */ 125 | QString getPath(const QString &queryString=""); 126 | 127 | 128 | 129 | signals: 130 | /*! 131 | * \brief eventResponseReady Sent after a 132 | * 133 | * QNetworkAccessManager::finished() signal is revived. 134 | * 135 | * Handle this * signal if you want to inspect the reply. 136 | * 137 | * \param replyData holds the reply's data. Result of calling reply->readAll() where 138 | * reply is the parameter passed to QNetworkAccessManager::finished(). 139 | */ 140 | void eventResponseReady(QByteArray replyData); 141 | 142 | /*! 143 | * \brief eventDataChanged Sent after a 144 | * 145 | * QNetworkReply::readyRead is received. It checks 146 | * for a "put" event with non empty data before forwarding the signal. 147 | * 148 | * \param changedData holds the update detected to the REST endpoint. 149 | * The first signal received is the initial contents of the endpoint. 150 | */ 151 | void eventDataChanged(QString changedData); 152 | 153 | private slots: 154 | void replyFinished(QNetworkReply*); 155 | void eventFinished(); 156 | void eventReadyRead(); 157 | private: 158 | void init(); 159 | 160 | 161 | QByteArray signMessage(QByteArray toSign, QByteArray privateKey); 162 | QString host; 163 | QString firebaseToken=""; 164 | QNetworkAccessManager *manager; 165 | QString buildPath(const QString &queryString = ""); 166 | void open(const QUrl &url); 167 | QString forceEndChar(const QString& string, char endCh); 168 | QString forceStartChar(const QString& string, char startCh); 169 | QByteArray trimValue(const QByteArray &line) const; 170 | }; 171 | 172 | #endif // FIREBASE_H 173 | --------------------------------------------------------------------------------