如何从 Firestore 云数据库中读取文档中的 ArrayLists?

Posted

技术标签:

【中文标题】如何从 Firestore 云数据库中读取文档中的 ArrayLists?【英文标题】:How can i read ArrayLists within a document from Firestore cloud database? 【发布时间】:2018-09-03 01:48:35 【问题描述】:

我正在尝试使用 Firestore 构建一个餐厅应用程序来存储订单和用户。

我尝试了 2 种方法,第一种是将订单的 ArrayList 作为数组写入 firestore 数据库,但之后无法读取它们... 我使用了DocumentSnapshot.toObject(myclassoflist.class),但这仅适用于文档中没有数组列表,仅适用于 values = ".."

然后我创建了一个文档集合(每个文档都是一个项目),其中包含作为简单值的数组 要了解这一点,请查看我的数据库

然后,要阅读它们,我首先要获取所有文档 ID

        db.collection("orders").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() 
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) 
            if (task.isSuccessful()) 
                for (DocumentSnapshot document : task.getResult()) 

                    documentsIDs.add(document.getId());

                
                Integer allIdsD = task.getResult().size();

                if (allIdsD.equals(documentsIDs.size())) 
                    readDocs();
                
            
        
    );

然后,对于每个文档 ID,我又创建了 3 个db.collection(collection).get(),以便再次使用函数DocumentSnapshot.toObject(myclass.class) 来获取子集合中每个文档的内部。

这里的问题是从数据库中获得一个完整的订单需要大约 0.8 秒,考虑到每天可能有 100 多个订单,这已经很长了

My project on GITHUB

示例来自:LimatexMM/app/src/main/java/g3org3/limatexmm/orders.java

编辑: 我也试着把命令写成如下:

    orderListBig docData = new orderListBig(list, currentUser, adList, docId);

(list是ArrayList,currentUser,adList是对象)

    db.collection("orderss").document(docId).set(docData)

然后阅读:

        db.collection("orderss").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() 
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) 
            if (task.isSuccessful()) 
                for (DocumentSnapshot document : task.getResult()) 

                    orderListBig ahah = document.toObject(orderListBig.class);

                    allOrders.add(ahah); (ArrayList of ordersListBig)

我的订单文件的一部分

【问题讨论】:

你可以代表你的ArrayList as HashMap 你能更明确一点吗?,我试着把顺序写成这样: Map docData = new HashMap(); docData.put("空", "填充"); docData.put("orderitems", list); docData.put("用户", currentUser); docData.put("附加", adList); db.collection("orderss").document(docId).set(docData) 其中 list 是一个 ArrayList 并且 currentUser, adlist 被声明为 class currentuser, ... 由于不知道你的Order长什么样,我就简单的ArrayList解释一下。如果您有列表["a", "b", "c"],它可能会在 Firebase 中保存为0: "a", 1: "b", 2: "c",一旦您开始删除数据,这将不会很好。如果你删除"b",你会留下0: "a", 2: "c",这不是连续数据,也就是数组。相反,您可以将列表另存为HashMap&lt;String, Boolean&gt;,即"a": true, "b": true, "c": true,现在您在删除数据时不受限制。 也许,在你的情况下,我们会HashMap&lt;OrderDocId, Boolean&gt;,其中OrderDocId 可能是String 在我的情况下,将被存储的数据要么被删除,要么被请求(读取),而且顺序比我发布的第一张照片中的简单列表要复杂得多,你可以看到数据如何存储在不同集合中的示例,并且在最后一张照片中是相同的数据,但存储在一个文档中,我无法使用 toObject 使用与我编写它时相同的类来读取该文档 【参考方案1】:

根据official documentation,关于在 Cloud Firestore 中使用数组,您需要知道:

虽然 Cloud Firestore 可以存储数组,it does not support 查询数组成员或更新单个数组元素。

如果您只想获取整个 orderList 数组并获取其值,例如 itemMore,则需要获取该特定文档的引用,然后像这样遍历 Map

Map<String, Object> map = documentSnapshot.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) 
    if (entry.getKey().equals("itemMore")) 
        Log.d("TAG", entry.getValue().toString());
    

但请注意,即使 orderList 对象作为数组存储在数据库中,entry.getValue() 也会返回 ArrayList,而不是 array

对于您的用例,我更好的方法是,如果您考虑这种替代数据库结构,其中每个项目都是映射中的键并且所有值都是 true:

orderList: 
    "itemMore": true,
    "itemMoreValue": true,
    "itemMoreOtherValue": true

英国电影学院! ;)

【讨论】:

我很难完全理解,但你是说我无法从 firestore 读取整个数组?我不需要更新数组,因为它只是一个项目列表客户购买了,我需要更新的只是“对象”中的一个值(存储在 firestore 中) ps:我的 orderList 看起来不像你的例子,正如你在我的上一张图片中看到的那样,有 2 个对象,additionalList和用户,其中包含有关订单日期/状态和客户端的信息,orderList 是对象列表 我不是说你不能读,我说的是能读,但是你看到它是一个数组的对象实际上是一个ArrayList。您的问题的标题是:“我如何阅读 ArrayLists”?现在你问如何更新。好的,您要更新哪个对象的哪个值? 抱歉混淆,我的问题仍然是如何使用单个命令读取我的 firestore 文档,因为(正如您在我的帖子中看到的)我只能使用多个文档、集合来阅读它并阅读仅包含 value = value(strings, numbers) 的文档,但这会导致仅一个订单的阅读时间约为 1 秒。如图所示,我的文档包含 1 个字符串(obtional,docid)、2 个对象(包含字符串、数字)和 1 个多个对象的列表 使用我上面的解决方案,对你没有帮助吗?你试过了吗? 我想阅读整个文档并将其作为我编写的对象(orderListBig),而不仅仅是一个值......

以上是关于如何从 Firestore 云数据库中读取文档中的 ArrayLists?的主要内容,如果未能解决你的问题,请参考以下文章