【问题标题】:How to retrieve Users' comment with their profile image and name?如何使用他们的个人资料图像和名称检索用户的评论?
【发布时间】:2020-09-26 17:45:16
【问题描述】:

目前,我正在制作一个社交媒体应用程序,并且我正在为我的项目使用 firebase firestore 和云存储。有一个评论按钮,如果用户单击该按钮,他应该能够看到每个用户的 cmets 及其姓名和头像。

这是我的firestore数据库结构,

Users(Root collection)
                     |---- UID1([Document]User ID which generate by authentication)---[Fields-Name,Image,Age]
                     |---- UID2([Document]User ID which generate by authentication)---[Fields-Name,Image,Age]

Posts(Root collection)
                     |-----DOCID1(Fields-Post Title,Posted_UID,Post_Image)
                                                                         |----Comments(Sub-collection)
                                                                                                     |----1RANDOMDOCID(Fields-Commented_User_Id,Commented_Date,Comment)
                                                                                                     |----2RANDOMDOCID(Fields-Commented_User_Id,Commented_Date,Comment)

好的,我需要将这些 cmets 填充到回收视图中。我将在下面添加我的方法,

  Query query = db.collection("Posts").document(CURRENT_SELECTED_DOC_ID).collection("Comments");
  PagedList.Config config = new PagedList.Config.Builder()
                .setEnablePlaceholders(false)
                .setInitialLoadSizeHint(10)
                .setPageSize(20)
                .build();
FirestorePagingOptions<CommentsI> options = new FirestorePagingOptions.Builder<CommentsI>()
                .setQuery(query, config, CommentsI.class)
                .build();

构造函数

public class CommentI {
String Commented_User_Id;
Date Commented_Date;
String Comment;
public CommentI(){
 //Empty constructor
}

public class CommentI(String commented_User_Id,Date commented_Date,String comment){
Commented_User_Id = commented_User_Id;
Commented_Date = commented_Date;
Comment = comment;
//------------------------------------------
public String getCommented_User_Id(){
return Commented_User_Id;
}
public Date getCommented_Date(){
return Commented_Date;
}
public String getComment(){
return Comment;
}

这是在 recycleview 中填充项目的常用方法。我可以毫无疑问地获得这些 cmets 和日期,但我需要同时设置用户的图像和名称。这就是我不得不停止工作直到解决这个问题的地方。请有人帮忙:)


编辑

这是我的适配器,当我们尝试像这样检索用户信息时,它总是在上下滚动时读取 firestore 文档。例如 - 当我上下滚动时(想想我在 recyleview 中有 10 个项目),每次从项目 1 滚动到 10 以及从项目 10 滚动到 1 时,我都可以看到名称和图像刷新。如何解决这个问题?

@Override
protected void onBindViewHolder(@NonNull final CommentIViewHolder holder, int position, @NonNull CommentI model) {
    holder.comment_textview.setText(model.getComment());
    holder.date_textview.setText(DateFormat.format("(yyyy-MM-dd)", model.getCommented_Date()));
    //getting UserID-------------
     String UserId = model.getCommented_User_Id();

    final FirebaseFirestore db = FirebaseFirestore.getInstance();
    DocumentReference documentReference = rootRef.collection("Users").document(UserId);

     documentReference.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()){
                DocumentSnapshot doc = task.getResult();
                   if (doc.exists()) {
                       String UserName = doc.getString("Name");
                       String UserImage = doc.getString("Image");
                       
           holder.commentor_name.setText(UserName);
                       holder.setProfile_image_view(UserImage);
                   }
               
            }
        }
    });





                
                

【问题讨论】:

    标签: java android firebase google-cloud-firestore


    【解决方案1】:

    好吧,我的错。我建议您使用 Firebase 用户 对象来存储 图像 URL 但您只能获取当前用户的图像(这不是您想要的)。

    因此需要存储在数据库中。现在,正如@Greg 所说,您有两种方法,我也建议您采用第二种方法,但如果您的用例需要采用第一种方法,那么您可以这样做:

    1.将用户的 UID 存储在 cmets 文档中您已经这样做了)。
    2.获取特定帖子的 cmets你也已经完成了)。

    现在,在此之后,您将在 onBindViewHolder 中获取用户的文档,这是强烈不鼓励,因为您的 onBindViewHolder 会在您的 recyclerView 中被多次调用,这会出现性能问题和成本上涨。

    通过查看您的代码,我假设您正在使用 FirebaseUI我没有经验),但我认为您应该自己执行此方法,例如这个(我最近遇到过这种情况,确实喜欢这个):

    3.获取特定帖子的 cmets 并将其存储在 ArrayList 之类的地方。
    4.遍历 cmets,获取每个用户的文档并将它们也存储在 Arraylist
    5.在适配器的构造函数中传递ArrayLists,然后在onBindViewHolder中设置它们

    现在,当我做类似这样的事情时,我在我的问题(给出的答案中)出现了你应该在此处看到的异常行为(如果你遵循这个答案)我自己):Running Firebase get() in a loop in android

    不过,这会花费你很多钱!

    【讨论】:

      【解决方案2】:

      TL;DR - 将图像和名称数据添加到您的评论文档中(并且仍然保留在用户文档中)


      从上面的信息中,我看到了两种可能的方法:

      1. 遍历收集评论者 UID 的 cmets,然后获取该 UID 的用户文档并在其中显示图像
      2. 首先创建评论文档时,将有关发表评论的用户的所有相关信息复制到评论文档中

      在这 2 种方法中,我强烈推荐第 2 种方法。

      在为 NoSQL 设计数据模型时(本质上是在确定将哪些数据放入文档时),请考虑您的应用程序以及您希望在给定屏幕上显示的内容。尝试将尽可能多的数据放在给定屏幕的单个文档中,以避免阅读额外的文档。

      对于具有 SQL 背景的人来说,这种方法会觉得“恶心”。在 SQL 领域,我们都接受过通过“数据规范化”消除数据重复的培训。这在很大程度上源于 SQL 起源于存储空间“昂贵”的世界。

      在 NoSQL 领域 - 例如 Firestore - 基本假设是

      • 存储很便宜
      • 写入(创建/更新/删除)很少且“昂贵”
      • 您获取的是原子的“文档”>>推论:没有“连接”

      在 NoSQL 领域,我们真的不介意数据重复。我们希望避免获取一个文档(评论)并被要求执行额外的文档获取(用户)。

      【讨论】:

      • 是的,您是对的,但是如果用户更改了他的姓名或个人资料并且此更改不适用于以前的 cmets,会发生什么情况?似乎firebase不适合社交媒体之类的应用程序或用户可以喜欢的任何其他应用程序。对吗?
      • @alex 是的,你是对的。尽管您可以在任何数据库中完成所有任务,但需要提出的问题是 - 数据库是否对您的用例有效。您也可以在 Firestore 中实现所有内容,但它对您的用例来说效率不高(至少我不这么认为),而且您将遇到的成本高得惊人。如果该应用程序只是一个尝试新事物的爱好项目,请确保您继续,但如果它是关于生产的,我建议不要使用 Firestore。
      • @s_o_m_m_y_e_e 是啊,我看到很多这样的cmets,我真的不明白为什么google不让firebase适合大多数情况。 :D 让我们看看 Firebase 专家对此有何看法
      • 实际上,这与 Firestore 无关。这是关于 SQL 与 NoSQL 数据库的对比。我们只需要为我们的用例选择哪个可以为我们提供更好的性能和更低的成本。
      • 不,不是你浪费了时间。不要小看 NoSql 数据库!正如我所说,我们只需要为我们的用例选择完美的产品。 SQL 和 NoSql 各有利弊。还有一个像 Firestore 这样的 NoSql 用例的最佳示例,我认为 RN 是电子商务库存。因此,您当然可以充分利用 Firestore,但在那些值得的情况下!甚至,我目前正在做一个 FireStore 项目。
      猜你喜欢
      • 1970-01-01
      • 2011-06-04
      • 2010-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-18
      相关资源
      最近更新 更多