123rightback123
123rightback123

Reputation: 124

How to properly parse a Firestore API JSON?

I'm using Google Cloud Firestore API for a project that involves simple retrieval of data from the server database. Having set up everything I can't seem to figure out how to properly parse the returned JSON, as all of my attempts have been unsuccessful. Using the Firestore package is out of question as this is a defined project.

I have tried the classic approach since Android studio only gets the field part with its HTTPURLConnection. This is the JSON structure:

{
    "documents": [
    {
        "name": "projects/...",
        "fields": {
            "name": {
                "stringValue": "Q1"
            },
            "myValues": {
                "arrayValue": {
                    "values": [
                    {
                        "stringValue": "First"
                    }
                    ]
                }
            },
            "index": {
                "integerValue": "0"
            }
        },
        "createTime": "2019-05-24T10:07:10.864421Z",
        "updateTime": "2019-05-28T07:52:34.445600Z"
    }
    ]
}

Here's my attempt at parsing it:


public ArrayList<Question> parse(String json)
{
    ArrayList<Question> list = new ArrayList<Question>();
    try {
        int indeks=0;
        String qName="";
        ArrayList<String> answerList= new ArrayList<String>();
        JSONObject object = new JSONObject(json);
        JSONArray dokumenti = object.getJSONArray("documents");
        for (int j = 0; j < dokumenti.length(); j++) {
            JSONObject jObject = dokumenti.getJSONObject(j);
            if (jObject.has("index")) indeks = jObject.getInt("index");
            if (jObject.has("name")) qName= jObject.getString("name");
            JSONArray answerArray= jObject.getJSONArray("myValues");
            for (int i = 0; i < answerArray.length(); i++) {
                try {
                    String answer= answerArray.getString(i);
                    answerList.add(answer);
                } catch (JSONException e) {
                    Log.d("OOPS", qName);
                }
            }
        }
        list.add(new Question(qName, qName, answerList, answerList.get(indeks), 0));
    }
    catch(JSONException e)
    {
        //something
    }
    return list;
}

Database structure

I expect that all of the documents get parsed and added to the list ArrayList but it seems like nothing happens and I can't find the TAG in the Logcat.

Upvotes: 1

Views: 1708

Answers (2)

Konstantin Tarkus
Konstantin Tarkus

Reputation: 38358

JavaScript example:

function toValue(field) {
  return "integerValue" in field
    ? Number(field.integerValue)
    : "doubleValue" in field
    ? Number(field.doubleValue)
    : "arrayValue" in field
    ? field.arrayValue.values.map(toValue)
    : "mapValue" in field
    ? toJSON(field.mapValue)
    : Object.entries(field)[0][1];
}

function toJSON(doc) {
  return Object.fromEntries(
    Object.entries(doc.fields ?? {}).map(([key, field]) => [key, toValue(field)])
  );
}

Upvotes: 0

Jaime Suarez
Jaime Suarez

Reputation: 660

It looks you're trying to get index before accessing its parent fields.

if (jObject.has("index")) indeks = jObject.getInt("index");

In this line you should have gotten before the parent object fields, otherwise you will not have access to index or name.

EDIT

I've been checking your code and you are parsing some things wrong. Let's go step by step:

  1. You are trying to access to the childs of fields without accessing to their parent. The solution following your structure would be something like this:
JSONObject jObject = dokumenti.getJSONObject(j);
JSONObject fields = jObject.getJSONObject("fields");
if (fields.has("index") && fields.getJSONObject("index").has("integerValue")) {
    indeks = fields.getJSONObject("index").getInt("integerValue");
}
if (fields.has("name") && fields.getJSONObject("name").has("stringValue")) {
    qName = fields.getJSONObject("name").getString("stringValue");
}
  1. You're trying to access also the myValues array not respecting the objects hierarchy. The correct way should be something like this:
JSONArray answerArray = fields.getJSONObject("myValues").getJSONObject("arrayValue").getJSONArray("values");
for (int i = 0; i < answerArray.length(); i++) {
   try {
      String answer = answerArray.getJSONObject(i).getString("stringValue");
      answerList.add(answer);
   } catch (JSONException e) {
      Log.d("OOPS", qName);
   }
}

With this changes I have been able to parse the Json you posted without any problem. Here you can find the complete code:

public ArrayList<Question> parse(String json)
    {
        ArrayList<Question> list = new ArrayList<Question>();
        try {
            int indeks = 0;
            String qName = "";
            ArrayList<String> answerList = new ArrayList<String>();
            JSONObject object = new JSONObject(json);
            JSONArray dokumenti = object.getJSONArray("documents");
            for (int j = 0; j < dokumenti.length(); j++) {
                JSONObject jObject = dokumenti.getJSONObject(j);
                JSONObject fields = jObject.getJSONObject("fields");
                if (fields.has("index") && fields.getJSONObject("index").has("integerValue")) {
                    indeks = fields.getJSONObject("index").getInt("integerValue");
                }
                if (fields.has("name") && fields.getJSONObject("name").has("stringValue")) {
                    qName = fields.getJSONObject("name").getString("stringValue");
                }
                JSONArray answerArray = fields.getJSONObject("myValues").getJSONObject("arrayValue").getJSONArray("values");
                for (int i = 0; i < answerArray.length(); i++) {
                    try {
                        String answer= answerArray.getString(i);
                        answerList.add(answer);
                    } catch (JSONException e) {

                        Log.d("OOPS", qName);
                    }
                }
            }
            list.add(new Question(qName, qName, answerList, answerList.get(indeks), 0));
        }
        catch(JSONException e)
        {
            //something
        }
        return list;
    }

Upvotes: 1

Related Questions