Unable to decode JSON payload from Firebase Integration

I am trying to decode this payload,

{"age":"\"25\"","bmi":"\"6\"","bp":"\"3\"","dpf":"\"7\"","glucose":"\"2\"","insulin":"\"5\"","preg":"\"1\"","skin":"\"4\""}

But unable to decode it correctly,

void getDataHandler(const char *topic, const char *data) {
	// This isn't particularly efficient; there are too many copies of the data floating
	// around here, but the data is not very large and it's not kept around long so it
	// should be fine.
	StaticJsonBuffer<256> jsonBuffer;
	char *mutableCopy = strdup(data);
	JsonObject& root = jsonBuffer.parseObject(mutableCopy);
	free(mutableCopy);

	Serial.printlnf("data: %s", data);

	// Because of the way the webhooks work, all data, including numbers, are represented as
	// strings, so we need to convert them back to their native data type here
	int age = atoi(root["age"]);
	int bmi = atoi(root["bmi"]);
	int bp = atoi(root["bp"]);
  int dpf = atoi(root["dpf"]);
  int glucose = atoi(root["glucose"]);
  int insulin = atoi(root["insulin"]);
  int preg = atoi(root["preg"]);
  int skin = atoi(root["skin"]);

Serial.printlnf("age=%d bmi=%d bp=%d", age, bmi, bp); 
}

it prints age=0 bmi=0 bp=0

I used MIT app inventor to send some number inputs to firebase bucket and using an integration to read those values on Particle device, see integration detail below,

{
    "event": "diabetes-get",
    "url": "https://srefsssssss-default-rtdb.firebaseio.com/data/data.json",
    "requestType": "GET",
    "noDefaults": true,
    "rejectUnauthorized": false,
    "query": {
        "auth": "tnwKxxxxxxxxxxxxxxxxxxxxxx"
    }
}

I think the payload is not in correct format but after many tries, I found no other ways (MIT app inventor send the data to the firebase in that manner/format only)

Those escaped double quotes (\") should not be part of the JSON string.
Maybe you could also show the AppInventor recipe that creates that JSON.

1 Like

Here is the App inventor recepie (Unable to upload image here, so here’e imgur link App Blocks

Even after modifying the data to look like this,

{"age":"256","bmi":"79","bp":"42","dpf":"43","glucose":"36","insulin":"16","preg":"52","skin":"23"}

It only prints 0 as output value for root[“age”]…,

StaticJsonBuffer<256> jsonBuffer;
char *mutableCopy = strdup(data);  // strdup() returns a pointer to a new copy of the string

  Serial.println(mutableCopy);
	JsonObject& root = jsonBuffer.parseObject(mutableCopy);
	free(mutableCopy); 
	

	// Because of the way the webhooks work, all data, including numbers, are represented as
	// strings, so we need to convert them back to their native data type here
	int age = atoi(root["age"]);
	int bmi = atoi(root["bmi"]);
	int bp = atoi(root["bp"]);
  int dpf = atoi(root["dpf"]);
  int glucose = atoi(root["glucose"]);
  int insulin = atoi(root["insulin"]);
  int preg = atoi(root["preg"]);
  int skin = atoi(root["skin"]);

  Serial.println(age);
  Serial.println(bmi);
  Serial.println(bp);
  Serial.println(dpf);
  Serial.println(glucose);
  Serial.println(insulin);
  Serial.println(preg);
  Serial.println(skin);

Can you also tell us which library you’re using?
I’d also check what the raw data renders before trying to translate into integers - maybe that’s the problem.

e.g.

  Serial.printlnf("age\t%s\r\n"
                  "bmi\t%s\r\n"
                  "bp\t%s\r\n"
                  "dpf\t%s\r\n"
                  "glucose\t%s\r\n"
                  "insulin\t%s\r\n"
                  "preg\t%s\r\n"
                  "skin\t%s\r\n\r\n"
                  , (const char*)root["age"]
                  , (const char*)root["bmi"]
                  , (const char*)root["bp"]
                  , (const char*)root["dpf"]
                  , (const char*)root["glucose"]
                  , (const char*)root["insulin"]
                  , (const char*)root["preg"]
                  , (const char*)root["skin"]
                 );
1 Like

@ScruffR Thanks a lot, fixed this using #include <ArduinoJson.h> library earlier was using SparkJson which was not working for me.
Payload still remains as the original one, I modified it to made in in correct format,

{"age":"\"25\"","bmi":"\"6\"","bp":"\"3\"","dpf":"\"7\"","glucose":"\"2\"","insulin":"\"5\"","preg":"\"1\"","skin":"\"4\""}

Here’s the code, the code might not be perfect but it saved my day :slight_smile:

StaticJsonDocument<256> doc;

  payload = data;
  payload.replace("\\""", "");
  payload.replace("\"\"", "\"");  
  payload.trim();
  
  snprintf(text, sizeof(text)-1, payload.c_str());
  // Serial.println(text);  

  // Deserialize the JSON document
  DeserializationError error = deserializeJson(doc, text);

  // Test if parsing succeeds.
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }
  else
  {
    Serial.println(F("deserializeJson() succeeded."));

    // Get the value of the element in the document, in exact same order we used while crating neuton model.
    inputs[0] = atof(doc["preg"]);
    inputs[1] = atof(doc["glucose"]);
    inputs[2] = atof(doc["bp"]);
    inputs[3] = atof(doc["skin"]);
    inputs[4] = atof(doc["insulin"]);
    inputs[5] = atof(doc["bmi"]);
    inputs[6] = atof(doc["dpf"]);
    inputs[7] = atof(doc["age"]);
1 Like

I’d not use snprintf() to copy the payload but rather go with this

  char text[strlen(data)+1)];
  strcpy(text, (const char*)payload);  
1 Like