【问题标题】:Why firebase is not able to query data from collection in recycler view?为什么 firebase 无法在回收站视图中从集合中查询数据?
【发布时间】:2021-01-22 01:13:44
【问题描述】:

我能够在 firebase 集合中获取数据,但它不会在回收站视图中查询该数据。 Recyclerview 不显示任何东西

这是 comment_list 类。

public class comment_list {
    public comment_list(String comments) {
        this.comments = comments;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    String comments;
}

这是comment_adapter 类

public class comment_adapter extends FirestoreRecyclerAdapter<comment_list, comment_adapter.comment_holder> {
  
    public comment_adapter(@NonNull FirestoreRecyclerOptions<comment_list> options) {
        super(options);
    }

    @Override
    protected void onBindViewHolder(@NonNull comment_holder holder, int position, @NonNull comment_list model) {
        holder.commment_on_post.setText(model.getComments());
    }

    @NonNull
    @Override
    public comment_holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment_recycler_dsign, parent, false);
        return new comment_holder(v);
    }

    public class comment_holder extends RecyclerView.ViewHolder{
      TextView commment_on_post;
        public comment_holder(@NonNull View itemView) {
            super(itemView);
            commment_on_post = itemView.findViewById(R.id.commenttextview);
        }
    }

这是评论类。在此我能够在 firebase 集合中获取数据,但不是在回收站视图中查询该数据。

public class Comments extends AppCompatActivity {
 ImageView profileimage;
 EditText addcommenttext;
 TextView postcommenttext;
    FirebaseFirestore db;
  
    RecyclerView comment_recycler_view;

   comment_adapter adaptercomment;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_comments);

        profileimage = findViewById(R.id.Addcommentprofileimage);
        addcommenttext = findViewById(R.id.addcommenttext);
        postcommenttext = findViewById(R.id.postcomment);
    
comment_recycler_view = findViewById(R.id.commentsrecycler);




        postcommenttext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (addcommenttext.equals("")) {
                    Toast.makeText(Comments.this, "Comment can't be empty", Toast.LENGTH_SHORT).show();
                } else {
                    String commentText = addcommenttext.getText().toString();

                    CollectionReference commentref = FirebaseFirestore.getInstance() .collection("CommentDetails");
                    commentref.add(new comment_list(commentText));

         

                    
                    FirebaseFirestore fbfs = FirebaseFirestore.getInstance();
                    CollectionReference commentrefs = fbfs.collection("CommentDetails");
                    Query query = commentrefs;

                    FirestoreRecyclerOptions<comment_list> options = new FirestoreRecyclerOptions.Builder<comment_list>()
                            .setQuery(query, comment_list.class)
                            .build();
                    adaptercomment = new comment_adapter(options);

                    comment_recycler_view.setHasFixedSize(true);
                    comment_recycler_view.setLayoutManager(new LinearLayoutManager(getApplication()));
                    comment_recycler_view.setAdapter(adaptercomment);
                    finish();
                    Toast.makeText(Comments.this, "Commented", Toast.LENGTH_SHORT).show();

                }
            }


    });

}

【问题讨论】:

  • 请发布您的数据库结构
  • 你数据库中的数据
  • 您在 Cloud Firestore 中的平均收藏?
  • 请编辑您的问题并将您的数据库结构添加为屏幕截图。请回复@AlexMamo
  • @AlexMamo 我确实请检查

标签: java android database firebase comments


【解决方案1】:

首先,让我们重新配置您的 Comments 活动类。建议在 onCreate 方法中初始化回收适配器,而不是在覆盖的 onClick 方法中。在当前设置下,每次触发 onClick 侦听器时都会初始化一个新的 comment_adapter。我们最好只设置一个。以下是更改后的情况(为了清楚起见,我添加了 cmets):

注意:为了清楚起见,我已重命名类、变量和方法以使用 java 和 android 约定。学习这些将极大地帮助您能够阅读其他人的代码,并为您自己的代码省去很多麻烦。

public class CommentsActivity extends AppCompatActivity {

    FirebaseFirestore db;
    CommentAdapter commentAdapter;

    ImageView profileImageView;
    EditText commentEditText;
    RecyclerView commentRecyclerView;
    Button addCommentButton; // Replaces the text view you are using

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        profileImageView = findViewById(R.id.add_comment_profile_image);
        commentEditText = findViewById(R.id.comment_edit_text);
        addCommentButton = findViewById(R.id.add_comment_button);
        commentRecyclerView = findViewById(R.id.comments_recycle_view);

        // Enables firestore debugging which will help a lot when trying to troubleshoot
        FirebaseFirestore.setLoggingEnabled(true);

        // We are now setting up our query directly within the OnCreate method.
        db = FirebaseFirestore.getInstance();
        Query query = db.collection("CommentDetails").orderBy("timestamp").limit(50);

        FirestoreRecyclerOptions<Comment> options = new FirestoreRecyclerOptions.Builder<Comment>()
                .setQuery(query, Comment.class)
                .build();

        // Setting up the recycle adapter in onCreate
        commentAdapter = new CommentAdapter(options);
        commentRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        commentRecyclerView.setAdapter(commentAdapter);

        // Set up your onClickListener just as before.
        addCommentButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // Note that the previous null check is unsuccessful. Previously, the object instance
                // was being checked, and not the contents of the edit text. This resolves that issue. (:
                if (commentEditText.toString().isEmpty()) {
                    Toast.makeText(CommentsActivity.this, "Comment can't be empty", Toast.LENGTH_SHORT).show();
                } else {
                    String commentText = commentEditText.getText().toString();
                    CollectionReference commentColRef = FirebaseFirestore.getInstance().collection("CommentDetails");
                    commentColRef.add(new Comment(commentText));
                    Toast.makeText(CommentsActivity.this, "Commented", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        commentAdapter.startListening();
    }

    @Override
    protected void onStop() {
        super.onStop();
        commentAdapter.stopListening();
    }
}

您会注意到添加了两个新方法:onStartonStop。在这些方法中,我们启动和停止附加到FirestoreRecyclerAdapter 的查询侦听器。参考FirebaseUI for Cloud Firestore read-me 会很有帮助。

请务必注意,在上面的代码中,我还将您的数据模型从 comment_list 重命名为 Comment。原因是这个类的一个实例只存储一个评论的状态。它不存储 cmets 列表。我认为当您尝试调试代码时可能会引起混淆。在使用 FirebaseUI 的情况下,绑定到回收视图的实际 cmets 列表(cmets 列表)由 FirebaseUI 代码以 数组的形式为您构建注释类实例。

为了清楚地了解这是如何完成的,花几个小时实现一个未连接到 Firestore 的简单回收视图和适配器可能会很有用。这样可以更好地了解 FirebaseUI 是如何做事的。 here 上有文档。

最后 - 这里是 comment_list 类的替代品:

public class Comment {

    String comment;
    @ServerTimestamp Date timestamp;

    // A zero argument constructor is required by firestore.
    public Comment() {
    }

    public Comment(String comment) {
        this.comment = comment;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public Date getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Date timestamp) {
        this.timestamp = timestamp;
    }

这里唯一的区别是有一个零参数(无参数)构造函数,这是 firestore 所需要的。

智者的话 - 我还没有看到你的视图模型项布局 (comment_recycler_dsign),但只需检查根布局的高度是否为“match_parent”。这是一个常见的错误。如果您只看到一个正在呈现的回收项目,最好先检查一下。

【讨论】:

  • 它有效,谢谢。你能告诉我如何订购查询,比如我发表评论然后它出现在顶部然后接下来出现在顶部?
  • 出现的问题是每条评论都显示在每个帖子中,而不是单个帖子中
  • @Harnoor 尝试在 Comment 类中添加“时间戳”字段。每次发表评论时,都会附上时间戳。然后将您的 firebase 查询编辑为 Query query = db.collection("chats").orderBy("timestamp").limit(50); 看看 (github.com/firebase/FirebaseUI-Android/tree/master/…)。示例实现非常适合您尝试做的事情。 (= 祝你好运!
  • 无法正常工作,评论发布不准确意味着评论未按照最新出现在发布
  • @Harnoor 这是一个你也可以参考的工作实现。 (: (github.com/michael-lundie/stackoverflow_temp) 我还使用时间戳功能更新了上述答案中的代码。
【解决方案2】:

放置一个监听器 上传完成后firebase会自动调用

 firestore.collection("").add(Any()).addOnCompleteListener { 
                    // do all your work here
 }

【讨论】:

  • OP,Harnoor,正在使用 FirebaseUI 和 FirestoreRecyclerAdapter。在这种情况下,侦听器通过适配器处理,分别调用它的startListening()stopListening() 方法。但是,在使用您自己的自定义适配器实现的情况下,当然需要上述内容。
猜你喜欢
  • 1970-01-01
  • 2019-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
相关资源
最近更新 更多