Firestore 从集合中获取数组

Posted

技术标签:

【中文标题】Firestore 从集合中获取数组【英文标题】:Firestore fetch array from collection 【发布时间】:2018-07-13 15:01:49 【问题描述】:

我在 firestore 中有一个集合,它返回的响应如下:

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

我如何为此响应创建模型并在 android 中解析这些数据。 在当前模型中,它返回 packs 为空,我正在获取数据 desc、名称和代码,但 packs 为空,packs 是一个数组。

获取数据的Java代码:

mFirestore.collection("catend").addSnapshotListener(new EventListener() @覆盖 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;
            

        

    
);

模型类:

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() 
        
    

调试结果:

You can see in the images

Firebase structure

Andoird studio log

【问题讨论】:

你遇到了什么问题? packs 是一个返回 null 的数组,我也分享了我的调试结果截图。请指导我..谢谢你 List&lt;Packs&gt; packs 更改为 Map&lt;String,Packs&gt; mapPacks 并从包中获取字段值使用 mapPacks.getObject("subcode"); 像这样 getmapPacks 返回 null 【参考方案1】:

Alex Mamo 的回答对我帮助很大,我更改了我的模型代码:

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;
    


我还更新了获取数据的 MainActivity.java 类:

 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;
                    

                

            
        );

输出: Android studio logcat

【讨论】:

List&lt;Packs&gt; packs; 更改为ArrayList&lt;Object&gt; packs; 没有区别,因为在Java 中,任何ArrayList 都是一个List 并且每个Packs 都是一个对象。解决方案是我在更新的答案中所写的。所以希望你重新考虑接受我的回答。【参考方案2】:

我在您的 Firestore 响应中看到 packs 对象是 List 而不是数组。我在你的模型类中也看到了同样的东西,List&lt;Packs&gt; packs

主要思想不是根据数据库中已有的数据创建模型类。所以一个问题是“我如何为这个响应创建模型?”是不正确的,因为事情不是这样运作的。首先创建模型类,然后按照构建帮助类的方式将数据添加到数据库中。

所以文档中的packs 属性实际上是Map。要打印这些值,请更改这行代码:

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

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);

您的输出将是:12 / s1 / 1

编辑:

再次查看您的模型类,您的代码中的问题是 getter。所以如果你想使用:

productModel.getPacksList();

请更改以下 getter:

public List<Packs> getPacksList() 
    return packs;

public List<Packs> getPacks() 
    return packs;

然后简单地调用:

productModel.getPacks();

就是这样!

【讨论】:

我如何解析这个响应:packs=[subcode=s1, weight=1, price=12], name=abc, desc=good, code=001,请提供一些代码以便我能理解你想说的内容 我在你的图片中看到的是null。您无法解析值为null 的东西。 这是我的问题,为什么它的comming null,因为packs里面有一些数据,你可以在这里查看,packs有子代码,重量和价格等数据,我的模型是错误的吗? ...packs=[subcode=s1, weight=1, price=12], name=abc, desc=good, code=001 其他值是否正确?请添加更详细的数据库结构。 我已经添加了我的 firestore 结构和 android studio 日志图像

以上是关于Firestore 从集合中获取数组的主要内容,如果未能解决你的问题,请参考以下文章

从 id 数组中获取 firestore 文档列表

Firestore 从文档的内部数组中获取数据

从 Firestore 文档中获取数据并附加到数组

如何从 firestore 两个集合中获取数据并将所有数据合并在一起

如何从firestore的路径中获取布尔值

如何使用 SwiftUI 将值数组写入 Firestore