Home > other >  Parse Firebase JSON array
Parse Firebase JSON array

Time:10-02

I need to parse the below JSON response from a Firebase Database. In this JSON sample, there are 2 documents qouap9 and 15p3vl. Both documents have multiple fields. I want to merge all of the fields' strings from each document to one line.

{
  "documents": [
    {
      "name": "projects/..",
      "fields": {
        "qouap9": {
          "stringValue": "A1:Hello;"
        },
        "5": {
          "stringValue": "A9:..."
        },
        "6": {
          "stringValue": "A10:..."
        }
      },
      "createTime": "2020-08-08T20:44:2",
      "updateTime": "2020-08-08T20:44:3"
    },
    {
      "name": "projects/..",
      "fields": {
        "15p3vl": {
          "stringValue": "A2:2020;"
        },
        "2": {
          "stringValue": "A6:..."
        },
        "t0w4yj": {
          "stringValue": "A4:2020;"
        },
        "1": {
          "stringValue": "A5:..."
        }
      },
      "createTime": "2020-10-20T06:58:2",
      "updateTime": "2020-10-20T06:58:2"
    }
  ]
}

I want the result to be like this :

A1:Hello; A9:... A10:...

A2:2020; A6:... A4:2020; A5:...

CodePudding user response:

Since last time I did not explain enough, here is another try.

implementation

uses
  System.JSON;

procedure DoSomeJSONStuff(const jsonstr: string);
var
  jo, fields: TJSONObject;
  ja: TJSONArray;
  jv: TJSONValue;
  i: integer;
  desiredstr: string;
begin

  // 1.
  jo := TJSONObject.ParseJSONValue(jsonstr) as TJSONObject;
  if (jo <> nil) then begin
    try

      // 2.
      ja := jo.GetValue('documents') as TJSONArray;

      // 3.
      for jv in ja do begin
        fields := (jv as TJSONObject).GetValue('fields') as TJSONObject;
        desiredstr := '';

        // 4.
        for i := 0 to fields.Count - 1 do begin
          desiredstr := desiredstr   (fields.Pairs[i].JsonValue as TJSONObject).GetValue('stringValue').Value;
        end;
        ShowMessage(desiredstr);
      end;
    finally

      // 5.
      jo.Free;
    end;
  end;
end;
  1. In jsonstr is your JSON as a string. With TJSONObject.ParseJSONValue you can parse your JSON and get a TJSONValue back if it does not fail. Otherwise the value is nil, hence the check for variable <> nil. Since TJSONObject is derived from TJSONValue, it can simply be cast explicitly in this case. Almost everything is derived from TJSONValue in the Delphi JSON framework. If you want to check if the TJSONValue is really your desired JSON container you could do it like this:

    var
     jv: TJSONValue;
     jo: TJSONObject;
    begin
      jv := TJSONObject.ParseJSONValue(jsonstr);
      if jv is TJSONObject then begin
        jo := (jv as TJSONObject);
        // code here
      end else
        raise Exception.Create('Unexpected container - expected: TJSONObject');
    
  2. The next step is to get the documents in your JSON. The value of that is an array. If you're not sure about the structure you could use TryGetValue instead of GetValue. You could check again if the returned value is actually a TJSONArray with variable is TJSONArray. I assume your structure is always the same.

  3. Now we iterate through the array with a simple for in loop.

  4. Since the element names of your fields do not have a "static" name we iterate through the fields by count. We get the TJSONValue and cast it as a TJSONObject. And for the TJSONObject we get the stringValues with GetValue('stringValue').Value and concatenate it to the desirestr variable.

  5. You only have to free your "main" variable/container as long as you only reference to it. Everything else is just a Pointer.

Edit #1: Hint about nil. Edit #2: Free memory.

  • Related