Firestore fetch array from collection

2020-08-04 10:17发布

问题:

I have collection in firestore which return the response as follows:

{packs=[{subcode=s1, weight=1, price=12}], name=abc, desc=Good, code=001}

How I can create model for this response and parse this data in Android. In the current model, It returns the packs null, I am getting the data desc, name and code but packs is null, packs is a array.

Java code for fetching data:

mFirestore.collection("catend").addSnapshotListener(new EventListener() { @Override public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {

        if (e != null) {
            Log.d(TAG, "onEvent: error" + e.getMessage());
        }

        for (DocumentChange document : documentSnapshots.getDocumentChanges()) {

            switch (document.getType()) {
                case ADDED:

                    ProductTest productModel=document.getDocument().toObject(ProductTest.class);
                    Log.d(TAG, "onEvent: response"+document.getDocument().getData());
                    Log.d(TAG, "onEvent: code="+productModel.getCode());  //work
                    Log.d(TAG, "onEvent: description="+productModel.getDesc()); //work
                    Log.d(TAG, "onEvent: name="+productModel.getName()); //work

                    Log.d(TAG, "onEvent: packs"+productModel.getPacksList()); //not work
                    break;
                case REMOVED:
                    break;
                case MODIFIED:
                    break;
            }

        }

    }
});

Model class:

public class ProductTest {
    String code,desc,name;
    List<Packs> packs;

    public ProductTest() {
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Packs> getPacksList() {
        return packs;
    }

    public void setPacksList(List<Packs> packsList) {
        this.packs = packsList;
    }

    public  class  Packs
    {
        String subcode;
        int price;

        public String getSubcode() {
            return subcode;
        }

        public void setSubcode(String subcode) {
            this.subcode = subcode;
        }

        public int getPrice() {
            return price;
        }

        public void setPrice(int price) {
            this.price = price;
        }

        public Packs() {
        }
    }
}

Debug result:

You can see in the images

Firebase structure

Andoird studio log

回答1:

Alex Mamo answer help me alot, I changed my model code:

public class ProductTest {
    String code,desc,name;
    ArrayList<Object> packs;

    public ArrayList<Object> getPacks() {
        return packs;
    }

    public void setPacks(ArrayList<Object> packs) {
        this.packs = packs;
    }

    public ProductTest() {
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

I also updated my MainActivity.java class where I am fetching data:

 mFirestore.collection("catend").addSnapshotListener(new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {

                if (e != null) {
                    Log.d(TAG, "onEvent: error" + e.getMessage());
                }
                for (DocumentChange document : documentSnapshots.getDocumentChanges()) {
                    switch (document.getType()) {
                        case ADDED:
                            ProductTest productModel=document.getDocument().toObject(ProductTest.class);
                            Log.d(TAG, "onEvent: response"+document.getDocument().getData());
                            Log.d(TAG, "onEvent: code="+productModel.getCode());  //work
                            Log.d(TAG, "onEvent: description="+productModel.getDesc()); //work
                            Log.d(TAG, "onEvent: name="+productModel.getName()); //work
                            Log.d(TAG, "onEvent: packs"+productModel.getPacks()); //Work
                            for (int i = 0; i <productModel.getPacks().size() ; i++) {
                                try {
                                    JSONObject jsonObject=new JSONObject(productModel.getPacks().get(i).toString());
                                    Log.d(TAG, "onEvent: subcode= "+jsonObject.getString("subcode"));
                                    Log.d(TAG, "onEvent: subprice="+jsonObject.getString("price"));
                                    Log.d(TAG, "onEvent: weight="+jsonObject.getString("weight"));

                                } catch (JSONException e1) {
                                    e1.printStackTrace();
                                }
                            }

                            break;
                        case REMOVED:
                            break;
                        case MODIFIED:
                            break;
                    }

                }

            }
        });

Output: Android studio logcat



回答2:

I see in your Firestore response that the packs object is a List and not an array. I also see the same thing in your model class, List<Packs> packs.

The main idea is not to create a model class according with the data that you already have in your database. So a question such "How I can create model for this response?" is not a correct, because this is not how the things works. You create the model class in the first place and then you add data to the database in the way you have structured your helper class.

So the packs property from your document si actually a Map. To print those value out please change this line of code:

Log.d(TAG, "onEvent: packs"+productModel.getPacksList()); //not work

with

Map<String, Object> packs = (Map<String, Object>) documentSnapshot.get("packs");
Map<String, Object> zero = (Map<String, Object>) packs.get("0");
String price = (String) zero.get("price");
String subcode = (String) zero.get("subcode");
String weight = (String) zero.get("price");
Log.d(TAG, price + " / " + subcode + " / " + weight);

Your output will be: 12 / s1 / 1

Edit:

Looking again at your model class, the problem in your code is the getter. So if you want to use:

productModel.getPacksList();

Please change the following getter:

public List<Packs> getPacksList() {
    return packs;
}

to

public List<Packs> getPacks() {
    return packs;
}

And then simply call:

productModel.getPacks();

That's it!