Library for Firebase, PUT, PATCH, POST, GET, DELETE operations supported, (others are available, todo). Based on Mbed's https-example. Tested on STM32F767 using ETHERNET and ESP8266 WIFI interfaces and STM32F446 using ESP8266 WIFI interface.

Dependents:   Firebase-Example

Revision:
0:768ae9838086
Child:
1:4f2c1fcc6fb6
diff -r 000000000000 -r 768ae9838086 Firebase.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Firebase.h	Thu Jan 23 22:18:11 2020 +0000
@@ -0,0 +1,237 @@
+#ifndef _FIREBASE_H_
+#define _FIREBASE_H_
+
+#include "mbed.h"
+#include "NetworkInterface.h"
+#include "https_request.h"
+
+/* List of trusted root CA certificates
+ * currently two: Amazon, the CA for os.mbed.com and Let's Encrypt,
+ * the CA for httpbin.org
+ * To add more root certificates, just concatenate them.
+ */
+const char SSL_CA_PEM[] =  
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIFmzCCBIOgAwIBAgIRAJRuZHok8dQjAQAAAAApJGwwDQYJKoZIhvcNAQELBQAw\n"
+    "QjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczET\n"
+    "MBEGA1UEAxMKR1RTIENBIDFPMTAeFw0xOTAzMTMyMTMwNTdaFw0yMDAzMTEyMTMw\n"
+    "NTdaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\n"
+    "Ew1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgTExDMRcwFQYDVQQDEw5m\n"
+    "aXJlYmFzZWlvLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALkd\n"
+    "/jeM+PrwIYmM6IE28iN7CjKnBWy+tqNrs5z2AJwM5iLgtgcbc+THuXGElTN7zAWB\n"
+    "SKWv+ezAGe5NiTEEUiWgX1z1VFDj85xpz+Cysn/Oi8MtoN6h8yCmYPtXv8YPInw0\n"
+    "JLkSM5e2uuWVwc/tR1Fh+awpiYQFqGm6DvMq6yAYB/nuL3Gyc4XFgRrxje+VQ+g3\n"
+    "oWE+9NVfqu4smFCutSIGlEdRhGdr/m2u+sc+dnBZNoVOqwSyyFyjpAZvMMvuE5Ip\n"
+    "3ovfA1tq57nl9eQw8fcKsdXOeeXYHc1KBUUC7Xb8F/1+upVML8a5GMULpYkClLXt\n"
+    "OKRRfCJa53YynILJdPkCAwEAAaOCAmQwggJgMA4GA1UdDwEB/wQEAwIFoDATBgNV\n"
+    "HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBS03YhV70g6\n"
+    "+7MUxtOiluRi1T2GAzAfBgNVHSMEGDAWgBSY0fhuEOvPm+xgnxiQG6DrfQn9KzBk\n"
+    "BggrBgEFBQcBAQRYMFYwJwYIKwYBBQUHMAGGG2h0dHA6Ly9vY3NwLnBraS5nb29n\n"
+    "L2d0czFvMTArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nL2dzcjIvR1RTMU8x\n"
+    "LmNydDArBgNVHREEJDAigg5maXJlYmFzZWlvLmNvbYIQKi5maXJlYmFzZWlvLmNv\n"
+    "bTAhBgNVHSAEGjAYMAgGBmeBDAECAjAMBgorBgEEAdZ5AgUDMC8GA1UdHwQoMCYw\n"
+    "JKAioCCGHmh0dHA6Ly9jcmwucGtpLmdvb2cvR1RTMU8xLmNybDCCAQIGCisGAQQB\n"
+    "1nkCBAIEgfMEgfAA7gB1ALIeBcyLos2KIE6HZvkruYolIGdr2vpw57JJUy3vi5Be\n"
+    "AAABaXkuFzgAAAQDAEYwRAIgVssWhLEYItcpljMfJfkBhnxUrw32ik3C7IyBhkS6\n"
+    "jQcCIAHzoq/0QsRXY8RITJ5z6pThPzJhiSeLhWb6v2MDs6+NAHUAXqdz+d9WwOe1\n"
+    "Nkh90EngMnqRmgyEoRIShBh1loFxRVgAAAFpeS4XEQAABAMARjBEAiBgwY3jVuyU\n"
+    "HTDrfXt7Hhq3AL9kD8hASq/qIXFvHAel1AIgV2DY0UI7PvVl2uHicvaL9BfUPQjP\n"
+    "8/7b5W5jd6HEKbowDQYJKoZIhvcNAQELBQADggEBAAFG/f9zTyPTiYjjbPKpIC3T\n"
+    "MMD8dWvny1DJpL2fQPMcpAkkduW7sFG8mLRh14mSBsWqAusj99nAKt6NJhxZewhp\n"
+    "JKwbcawanW+w2DUzFr0FauVxNIs4xPxcgkCNAGeUj8ZI+cDcSaMOY4WxNrjOgbbI\n"
+    "feOxHsCmIWxch6/vNVxh+54BZFCy723DL8Fo/tDRU73b+gxPJusJva4ABuXSqSFT\n"
+    "EDaRGzdj8AKkoDmRkWLcEg/6a/2dfw8VV7fIAlqVxNQwZWZLtIsBGazxZ5xflrVz\n"
+    "I5AHejNR7guDaWAimhkSOlG11W8BzPtdAo/xJ6JyI4K5kPGIXucniVRmQfmojxc=\n"
+    "-----END CERTIFICATE-----\n"
+    "-----BEGIN CERTIFICATE-----\n"
+    "MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMSAw\n"
+    "HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs\n"
+    "U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEy\n"
+    "MTUwMDAwNDJaMEIxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3Qg\n"
+    "U2VydmljZXMxEzARBgNVBAMTCkdUUyBDQSAxTzEwggEiMA0GCSqGSIb3DQEBAQUA\n"
+    "A4IBDwAwggEKAoIBAQDQGM9F1IvN05zkQO9+tN1pIRvJzzyOTHW5DzEZhD2ePCnv\n"
+    "UA0Qk28FgICfKqC9EksC4T2fWBYk/jCfC3R3VZMdS/dN4ZKCEPZRrAzDsiKUDzRr\n"
+    "mBBJ5wudgzndIMYcLe/RGGFl5yODIKgjEv/SJH/UL+dEaltN11BmsK+eQmMF++Ac\n"
+    "xGNhr59qM/9il71I2dN8FGfcddwuaej4bXhp0LcQBbjxMcI7JP0aM3T4I+DsaxmK\n"
+    "FsbjzaTNC9uzpFlgOIg7rR25xoynUxv8vNmkq7zdPGHXkxWY7oG9j+JkRyBABk7X\n"
+    "rJfoucBZEqFJJSPk7XA0LKW0Y3z5oz2D0c1tJKwHAgMBAAGjggEzMIIBLzAOBgNV\n"
+    "HQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1Ud\n"
+    "EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJjR+G4Q68+b7GCfGJAboOt9Cf0rMB8G\n"
+    "A1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEBBCkwJzAl\n"
+    "BggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzAp\n"
+    "MCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3NyMi5jcmwwPwYDVR0g\n"
+    "BDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9y\n"
+    "ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAGoA+Nnn78y6pRjd9XlQWNa7H\n"
+    "TgiZ/r3RNGkmUmYHPQq6Scti9PEajvwRT2iWTHQr02fesqOqBY2ETUwgZQ+lltoN\n"
+    "FvhsO9tvBCOIazpswWC9aJ9xju4tWDQH8NVU6YZZ/XteDSGU9YzJqPjY8q3MDxrz\n"
+    "mqepBCf5o8mw/wJ4a2G6xzUr6Fb6T8McDO22PLRL6u3M4Tzs3A2M1j6bykJYi8wW\n"
+    "IRdAvKLWZu/axBVbzYmqmwkm5zLSDW5nIAJbELCQCZwMH56t2Dvqofxs6BBcCFIZ\n"
+    "USpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg==\n"
+    "-----END CERTIFICATE-----\n";
+
+/*
+    // how to build the Firebase connection FirebaseUrl string for 'method overide'
+    
+    strcpy(FirebaseUrl, FirebaseID);                // Firebase account ID
+    
+    // this bit in the middle to send .json data structure and authority
+    // for any REST api functions e.g. GET, PUT, POST, PATCH, DELETE
+    // replace the PUT with required function
+    
+    strcat(FirebaseUrl, "/Parent/Child/.json?x-http-method-override=PUT&auth=");
+    strcat(FirebaseUrl, FirebaseAuth);              // Firebase account authorisation key
+*/
+
+// set Firebase project information..
+char    FirebaseUrl[300];   // dimension to suit required character space
+const char FirebaseID[100]  = "https://projectID.firebaseio.com";   // project ID 
+const char FirebaseAuth[100]= "Web API key";                        // web API key
+
+char* getData;
+
+/*
+  Connects to the network using the mbed_app.json ESP8266 WIFI networking interface,
+  you can also swap this out with a driver for a different networking interface or
+  if you use ETHERNET: change mbed_app.json "target.network-default-interface-type" : "ETHERNET",
+*/
+ 
+NetworkInterface*   network;
+TLSSocket* socket = new TLSSocket();
+nsapi_error_t r;
+ 
+NetworkInterface *connect_to_default_network_interface() {
+    printf("Connecting to network...\n\n");
+
+    NetworkInterface* network = NetworkInterface::get_default_instance();
+
+    if (!network) {
+        printf("No network interface found, select an interface in 'mbed_app.json'\n");
+        return NULL;
+    }
+    nsapi_error_t connect_status = network->connect();
+    if (connect_status != NSAPI_ERROR_OK) {
+        printf("Failed to connect to network (%d)\n", connect_status);
+        return NULL;
+    }
+    printf("Connected to the network!\n");
+    printf("IP address: %s\n", network->get_ip_address());
+    printf("MAC: %s\n", network->get_mac_address());
+    printf("Netmask: %s\n", network->get_netmask());
+    printf("Gateway: %s\n", network->get_gateway());   
+    return network;
+}
+   
+void startTLSreusesocket(char *FirebaseID) { 
+          
+    if ((r = socket->open(network)) != NSAPI_ERROR_OK) {
+        printf("TLS socket open failed (%d)\n", r);
+    }
+    if ((r = socket->set_root_ca_cert(SSL_CA_PEM)) != NSAPI_ERROR_OK) {
+        printf("TLS socket set_root_ca_cert failed (%d)\n", r);
+    }
+    if ((r = socket->connect(FirebaseID, 443)) != NSAPI_ERROR_OK) {
+        printf("TLS socket connect failed (%d)\n", r);
+    }
+}
+
+void dump_response(HttpResponse* res) {
+    mbedtls_printf("Status: %d - %s\n", res->get_status_code(), res->get_status_message().c_str()); 
+    mbedtls_printf("Headers:\n");
+    for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
+        mbedtls_printf("\t%s: %s\n", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str());
+    }
+    mbedtls_printf("\nBody (%d bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str());
+}
+
+char *getFirebase(char* FirebaseUrl)
+{       
+    //HttpsRequest* get_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET, FirebaseUrl);  // non socket reuse function
+    HttpsRequest* get_req = new HttpsRequest(socket, HTTP_GET, FirebaseUrl);    // socket reuse function 
+    HttpResponse* get_res = get_req->send();    
+    if (!get_res) {       
+        time_t seconds = time(NULL);                                        
+        printf("Https GET failed (error code %d), %s", get_req->get_error(), ctime(&seconds));        
+        socket->close();
+        delete socket;  
+        delete get_req;
+        TLSSocket* socket = new TLSSocket();
+        startTLSreusesocket((char*)FirebaseID); // restart TLS reuse socket if failure 
+        return 0;}
+        else{
+            //dump_response(get_res);
+            delete get_req;
+            getData = (char*)get_res->get_body_as_string().c_str();                
+            return getData;
+            }
+} 
+
+bool putFirebase(char* FirebaseUrl, char *stringToProcess)
+{
+    //HttpsRequest* put_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_PUT, FirebaseUrl);    // non socket reuse function
+    HttpsRequest* put_req = new HttpsRequest(socket, HTTP_PUT, FirebaseUrl);    // socket reuse function   
+    put_req->set_header("Content-Type", "application/json");
+    HttpResponse* put_res = put_req->send(stringToProcess, strlen(stringToProcess));    
+    if (!put_res) {
+        time_t seconds = time(NULL);                                        
+        printf("Https PUT failed (error code %d), %s", put_req->get_error(), ctime(&seconds));
+        socket->close();
+        delete socket;   
+        delete put_req;
+        TLSSocket* socket = new TLSSocket();                            
+        startTLSreusesocket((char*)FirebaseID); // restart TLS reuse socket if failure 
+        return 0;                
+        }
+        else{
+            // dump_response(put_res);   
+            delete put_req;     
+            return put_res; 
+            } 
+}
+
+bool postFirebase(char* FirebaseUrl, char *stringToProcess)
+{  
+   // HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, FirebaseUrl);   // non socket reuse function
+    HttpsRequest* post_req = new HttpsRequest(socket, HTTP_POST, FirebaseUrl);  // socket reuse function   
+    post_req->set_header("Content-Type", "application/json");
+    HttpResponse* post_res = post_req->send(stringToProcess, strlen(stringToProcess));    
+    if (!post_res) {
+        time_t seconds = time(NULL);                                        
+        printf("Https POST failed (error code %d), %s", post_req->get_error(), ctime(&seconds));
+        socket->close();
+        delete socket;
+        delete post_req;
+        TLSSocket* socket = new TLSSocket();
+        startTLSreusesocket((char*)FirebaseID); // restart TLS reuse socket if failure 
+        return 0;
+        }
+        else{
+            //dump_response(post_res);    
+            delete post_req;     
+            return post_res;
+            }           
+}
+
+bool deleteFirebase(char* FirebaseUrl, char *stringToProcess)
+{
+    // HttpsRequest* delete_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_DELETE, FirebaseUrl);   // non socket reuse function
+    HttpsRequest* delete_req = new HttpsRequest(socket, HTTP_DELETE, FirebaseUrl);  // socket reuse function   
+    delete_req->set_header("Content-Type", "application/json");
+    HttpResponse* delete_res = delete_req->send(stringToProcess, strlen(stringToProcess));    
+    if (!delete_res) {
+        time_t seconds = time(NULL);                                        
+        printf("Https DELETE failed (error code %d), %s", delete_req->get_error(), ctime(&seconds));
+        socket->close();
+        delete socket;
+        delete delete_req;
+        TLSSocket* socket = new TLSSocket();
+        startTLSreusesocket((char*)FirebaseID); // restart TLS socket reuse if failure 
+        return 0;
+        }
+        else{
+            //dump_response(delete_res);    
+            delete delete_req;     
+            return delete_res;
+            }    
+}
+
+#endif // _FIREBASE_H_