【问题标题】:Android - retrieve custom objects stored in a document in Cloud FirestoreAndroid - 检索存储在 Cloud Firestore 文档中的自定义对象
【发布时间】:2018-04-03 02:12:51
【问题描述】:

我使用 Cloud Firestore 如下:

“事件”集合包含使用唯一事件 ID 作为名称的文档。在这些文档中有许多“EventComment”对象——每个对象代表用户发表的评论。

要将“EventComment”对象添加到文档中,我使用以下内容:

EventComment mcomment = new EventComment();
mcomment.setComment("this is a comment");
Map<String, EventComment> eventMap = new HashMap<>();
eventMap.put(Long.toHexString(Double.doubleToLongBits(Math.random())), mcomment);

    firestore.collection("events").document(event_id)
            .set(eventMap, SetOptions.merge()).addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
            Toast.makeText(EventCommentsActivity.this, "ya bastud", Toast.LENGTH_SHORT).show();
        }
});

我创建了一个 HashMap 的 String 和我的对象“EventComment”,然后在文档中设置它。

但是,当我想检索给定文档中包含的所有“EventComment”对象时,我无法将其转换为 EventComment 对象,即我不能这样做:

    DocumentReference docRef = db.collection("events").document("vvG17ZfcLFVna8");
docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
        EventComment comment = documentSnapshot.toObject(EventComment.class);
    }
});

此外,尝试将 documentSnapshot 强制转换为 HashMap 会给出“未经检查的强制转换”消息,并最终失败。这个想法是使用 cmets 来填充 RecyclerView。

我想我可能需要重新构建我存储数据的方式?

任何建议将不胜感激。

干杯

【问题讨论】:

    标签: java android firebase google-cloud-firestore


    【解决方案1】:

    您猜对了,您需要重新构建存储数据的方式。我说这是因为您在实际数据库中存储类型EventComment 的对象的方式不正确。正如您在有关Quotas and Limits 的官方文档中看到的,文档的最大大小为1MiB。所以如果你继续这样存储数据,你会在很短的时间内达到1MiB的极限。

    请记住,Cloud Firestore 已针对存储大量小文档进行了优化。为了解决这个问题,我建议您像这样更改数据库结构:

    Firestore-root
       |
       --- events (collection)
       |     |
       |     --- eventId (document)
       |     |     |
       |     |     --- //event details
       |     |
       |     --- eventId (document)
       |           |
       |           --- //event details
       |
       --- comments (collection)
             |
             --- eventId (document)
                   |
                   --- eventComments (collection)
                         |
                         --- eventCommentId (document)
                         |      |
                         |      --- //event comment details
                         |
                         --- eventCommentId (document)
                                |
                                --- //event comment details
    

    如您所见,EventComment 类型的每个对象都作为单独的文档添加到 events 集合中。要读取所有事件对象,请使用以下代码:

    DocumentReference docRef = db.collection("events");
    docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
        @Override
        public void onSuccess(DocumentSnapshot documentSnapshot) {
            EventComment comment = documentSnapshot.toObject(EventComment.class);
        }
    });
    

    编辑:

    如果您想要给定 eventId 的 commnets 列表,请再次查看上面的数据库结构,看看它是如何表示的。如您所见,我添加了一个名为 comments 的新集合,其中给定 eventId 中的每个新评论也存储为单独的文档。我想出了这个结构来避免嵌套地图。

    如果您有兴趣,可以看看我的一个tutorials,其中我已逐步解释了如何构建应用程序所需的数据库。

    【讨论】:

    • 嗨,亚历克斯,感谢您的回复。这确实更有意义,但是如果我想要给定 eventID 的“commnets”列表,如何最好地表示?我的代码中的模型是否需要定义一个列表,或者我可以有一个 cmets 的子集合? EventComment 模型旨在表示 1 位用户发表的 1 条评论
    • 不客气@Zach 要实现你想要的,请查看我的更新答案。
    • 嗨,Alex,我看了你的教程,它非常有用 - 谢谢!它确实有效,我能够获取集合,然后将其映射到代码中的 ArrayList。我现在正在看你的 Firebase RecyclerView 教程 :)
    • 得到它在 RecyclerView 中的填充,感谢您的教程和 Stackoverflow 问答:)
    猜你喜欢
    • 2019-02-20
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 2020-04-23
    • 2011-10-10
    相关资源
    最近更新 更多