为什么 firebase 无法在回收站视图中查询集合中的数据?

Why firebase is not able to query data from collection in recycler view?

我能够在 firebase 集合中获取数据,但它不会在回收器视图中查询该数据。 Recyclerview 没有显示任何内容

这是comment_listclass。

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_adapterclass

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

这是评论 class。在此我能够在 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();

                }
            }


    });

}

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

注意:为清楚起见,我已重命名 classes、变量和方法以使用 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。这样做的原因是 class 的一个实例只存储一条评论的状态。它不存储评论列表。我认为这可能会在您尝试调试代码时引起混淆。在使用 FirebaseUI 的情况下,绑定到您的回收视图的实际评论列表(评论列表)是由 FirebaseUI 代码以数组的形式为您构建的评论class个实例。

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

的文档

最后 - 这是 comment_list class 的替代品:

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

这里唯一的区别是有一个 zero-args(无参数)构造函数,这是 firestore 所必需的。

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

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

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