How to store data correctly to Firebase Realtime Database

Viewed 103

I am creating a google add-on that extracts info from the form. I was able to grab the data and store it in a JSON object. However, when I upload the results to Firebase Realtime Database, it stores weirdly (refer to the screenshot below).

enter image description here

The following is how I would like to upload the data to Firebase: enter image description here

The following is the code where I create the JSON object. Any help would be appreciated.

function makeJSON(form_title, ques_type, form_question, number_of_choices, multi_options, multi_answer, checkBox_options, checkBox_answer, number_of_questions) {
  let type_of_question = ques_type.split("~ ");
  let questions = form_question.split("~ ");
  let mult_options = multi_options.split("~ ");
  let mult_answer = multi_answer.split("~ ");
  let check_options = checkBox_options.split("~ ");
  let check_answer = checkBox_answer.split("~ ");

  let multi_answer_list = [];
  let checkbox_answer_list = [];
  var newDate = new Date();
  var dateAdded = newDate.toLocaleString("en-US");

  let jsonObj = "{";

  //stores and formats forms data in json object
  for(var i = 0; i < number_of_questions; i++){
    if(i < number_of_questions){
        
      var count = number_of_choices[i]
      jsonObj += '"' + [i+1] + '"' + ":{" + '"question-type"' + ":" + '"' + type_of_question[i] + '",' + '"question"' + ":" + '"' + questions[i] + '",';
      
      for (var k = 0; k < count; k++) { 
        if(type_of_question[i] === "Multiple Choice"){
          jsonObj += '"' + "option" + [k+1] + '"'  + ":" + '"' + mult_options[k] + '"' + ",";
        }
        if(type_of_question[i] === "CheckBox"){
          jsonObj += '"' + "option" + [k+1] + '"' + ":" + '"' + check_options[k] + '"' + ",";        
        }
      }

      for (var j = 0; j < count; j++) {  
        if(type_of_question[i] === "Multiple Choice"){
         if(mult_answer[j].trim().toLowerCase() === 'true'){
            multi_answer_list.push(mult_options[j]);
            //jsonObj += '"' + "answer" + [j+1] + '"' + ":" + '"' + mult_options[j] + '"' + ",";
          }
        }

        if(type_of_question[i] === "CheckBox"){
          if(check_answer[j].trim().toLowerCase() === 'true'){
            checkbox_answer_list.push(check_options[j]);
            //jsonObj += '"' + "answer" + [j+1] + '"' + ":" + '"' + check_options[j] + '"' + ",";
          }
        }
      }

      if(i < number_of_questions){
        if(type_of_question[i] === "Multiple Choice"){
          jsonObj += '"' + "answer" + '"' + ":" + '"' + multi_answer_list.join(",") + '"' + ",";   
        } 
        if(type_of_question[i] === "CheckBox"){
          jsonObj += '"' + "answer" + '"' + ":" + '"' + checkbox_answer_list.join(",") + '"' + ",";
        } 
      }

      if(type_of_question[i] !== "Multiple Choice" && type_of_question[i] !== "CheckBox"){
        jsonObj += '"' + "answer" + '"' + ":" + '"false"' + ","; //default value
      }

      if(i < number_of_questions-1){
        jsonObj += '"' + "date added" + '"' + ":" + '"' + dateAdded + '"' + "},"; //default value
      } else{
        jsonObj += '"' + "date added" + '"' + ":" + '"' + dateAdded + '"' + "}"; //default value
      }
    }
  }
  jsonObj += "}";
  console.log(jsonObj);

  sendExtractedData(form_title, jsonObj)
}

UPDATE: The following is the approach that I decided to go with (using push()). I was not able to get the structure (screenshot above) but this is close to what I am looking for:

function makeJSON(form_title, type_of_question, questions, multi_options, multi_answer, checkBox_options, checkBox_answer, number_of_questions) {
      var dateAdded = new Date().toLocaleString("en-US"), quesList;
      let multiple_option = [], checkbox_option = [], multiple_answer = [], checkbox_answer = [], constructedJSON = {};
      var uniqueQuizID = Utilities.getUuid(), num, x;
    
      /** set list of options and answers **/
      for(var k = 0; k < multi_options.length; k++){
        multiple_option.push(multi_options[k]);
        if(multi_answer[k]){
          multiple_answer.push(multi_options[k]);
        }
      }
      for(var j = 0; j < checkBox_options.length; j++){
        checkbox_option.push(checkBox_options[j]);
        if(checkBox_answer[j]){
          checkbox_answer.push(checkBox_options[j]);
        }
      }
     /****/
    
     console.log(uniqueQuizID);
    
     constructedJSON.quiz_title = form_title;
      
      //stores and formats forms data in json object
      for(var i = 0; i < number_of_questions; i++){
        if(type_of_question[i].trim() === "Multiple Choice"){
          quesList = {"item-type":type_of_question[i], "question":questions[i], "question-options":multiple_option, "question-responses":multiple_answer, "question-submitted":dateAdded};
          x= i+1;
          num = ''+ x;
          constructedJSON[num] = quesList;
        } else if(type_of_question[i].trim() === "CheckBox"){
          quesList = {"item-type":type_of_question[i], "question":questions[i], "question-options":checkbox_option, "question-responses":checkbox_answer, "question-submitted":dateAdded};
          x= i+1;
          num = ''+ x;
          constructedJSON[num] = quesList;
        } else{
          quesList = {"item-type":type_of_question[i], "question":questions[i], "question-submitted":dateAdded};
          x= i+1;
          num = ''+ x;
          constructedJSON[num] = quesList; 
        }
      }

  //console.log(constructedJSON);
  sendExtractedData(uniqueQuizID, constructedJSON);
}
1 Answers

This construct in your code:

jsonObj += '"' + [i+1] + '"' + ":{"...

Is just a very convoluted way to construct an array without an element at the 0th index. Firebase will store it as a JSON object with sequential numeric keys, and then coerce it back to an array when you read it.

I recommend:

  • Either storing it as an actual array with jsonObj[i+1] = '"' + ":{"
  • Or using keys that are not just numbers: ``jsonObj['key_'+(i+1)] = ...`, to prevent Firebase from coercing it into an array.

And either way I'd strongly recommend to:

  • Don't use string concatenation to construct a JSON object. At best it is just harder to read, but it's actually really easy to make a mistake in there.

    This entire line:

    jsonObj += '"' + [i+1] + '"' + ":{" + '"question-type"' + ":" + '"' + type_of_question[i] + '",' + '"question"' + ":" + '"' + questions[i] + '",';
    

    Would be much more readable like this:

    jsonObj[i] = { question-type: type_of_question[i], question: questions[i] };
    
  • Consider not using an array, but use push() for the keys. For more on why, read Best Practices: Arrays in Firebase.

Related