Properly Making HTTP POST Requests From Spark Core

Hi everyone, I am having trouble making a HTTP POST request from my core to firebase.

The method works via command line:

curl -X POST -d '{"value":1,"number": 99}' https://{my-domain}.firebaseio.com/{my-path}.json

Here is my current code on the core:

if(client.connect("{my-domain}.firebaseio.com", 80)) {

    // Connection succeeded
    char msg[] = "{'value': 5, 'number': 99}";
    
    client.println("POST /{my-method}.json HTTP/1.1");
    client.println("Host: {my-domain}.firebaseio.com");
    client.print("Content-Length: ");
    client.println(strlen(msg));
    client.println();
    
    client.println(msg);

    delay(1000);
    client.flush();
    client.stop();

  } else {
        // Connection failed
        Spark.publish("ERROR","Connection to firebase failed...2");
        
    }

I have not added a key to firebase yet, so I don’t think it is an authentication/authorization problem.

I would assume this has been done before many times, I think I’m just missing something small. Thanks in advance!

Is it https? The core can’t do https :frowning:

But it’s perfect for a webhook :slight_smile: search for webhook and you will see some examples

I realized I can’t do it via https from the core, I turned to using curl and php.

-Disclaimer 1: this is basic test code for a proof of concept…I wouldn’t use it in production
-Disclaimer 2: I referenced work by ktamas77 on github – nice work!

Process is:

  1. When the event happens I’ll make an HTTP GET request to my server, passing in url path parameters
  2. The server will then use php cURL to make the HTTP POST to Firebase

My server code (php) is as follows:

             //curl vars
             $url = "https://{my-domain}.firebaseio.com/$deviceID.json";
		
		$postData = array(
				"value" => $rating,
				"timestamp" => 'a timestamp',
				"how" => "via post curl"
		);
 
	    $ch = curl_init();  
	 
	    $jsonData = json_encode($postData);
	    
	    $header = array(
	    		'Content-Type' => "application/json",
	    		'Content-Length' => strlen($jsonData)
	    );
	    

	    try {
		    curl_setopt($ch, CURLOPT_URL,$url);
		    curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
		    
		    
		    
		    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
		    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
		    
		    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
		    curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
		    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
		    
		    
		    $output=curl_exec($ch);
		 
		    curl_close($ch);
		    
	    } catch (Exception $e) {
	    	
	    	print $e;
	    	echo 'bob saget';
	    }
	    
	    echo 'success';
	    return $output;
        }

My core code is:

   if (client.connect("{my-domain}", 80))  {

    // Connection succesful, update datastreams

    client.print("GET /path/to/stuff/");
    client.print(Spark.deviceID());
    client.print("/");
    client.print(arbitraryData);
    client.print("/1");
    client.println(" HTTP/1.1");
    client.println("Host: {my-domain}");
    client.println("Accept: text/html, text/plain, application/json");
    client.println("User-Agent: Arduino/1.0");
    client.println("Content-Length: 0");
    client.println();
else 
{
    // Connection failed
    Spark.publish("ERROR","Connection Failed");
}

@Hootie81 you are exactly right. I posted the solution I arrived at below (note it is test code - not production ready).

In your core code above you don’t check or clear the response from the server. This will fill up the receive buffer and cause a hard fault on the core. There are a few posts about the problem on the forum… something to watch out for

Further down in the code I perform the following operations:

client.flush();
client.stop();

I don’t check the server response on purpose. Will this take care of the buffer?

The client.flush doesn’t do the job unfortunately. .

Try

while (client.available()) client.read(); // makeshift client.flush() 

Hi.

Has anyone get the HTTP POST request to work on core yet?
I have tried all your suggestion above but I could not get it to work.

My test bed is quite simple. On the server side I run Node.js with a simple thread to accept a Post request on port 8888. I tested this with a simple JavaScript post a form to it and it replies back fine. So, that part is tested.

On the core… most of the time I tested with the TCPClient, codes… 99% of the time it cannot connect to the server. The other 1% of time, it connected but my server did not see the request coming in.

I also did a code using HTTPClient.h library… well, it could not compile due to many errors.

So, can someone post a working code for sending HTTP POST please…

@jbyars4ku I’m interested in the code that you are referring to, but I don’t see it. Was it removed?
Thanks,