为什么 Firebase 不能从集合中查询数据以在循环视图中显示?

huangapple go评论76阅读模式
英文:

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

问题

// This is the comment_list class.
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;
}

// This is the comment_adapter class.
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);
        }
    }
}

// This is the Comments class.
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();
                }
            }
        });
    }
}

Please note that the XML layout files and certain variable declarations (e.g., R.layout.comment_recycler_dsign, R.id.Addcommentprofileimage, etc.) are not provided in the code snippet, as you requested only the translation of the code itself. Make sure to integrate these elements appropriately in your Android project.

英文:

I am able to get data in firebase collection but it does not query that data in recycler view. Recyclerview does not showing anything为什么 Firebase 不能从集合中查询数据以在循环视图中显示?

This is the comment_list class.

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

This is comment_adapter class

public class comment_adapter extends FirestoreRecyclerAdapter&lt;comment_list, comment_adapter.comment_holder&gt; {
public comment_adapter(@NonNull FirestoreRecyclerOptions&lt;comment_list&gt; 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);
}
}

This is Comments class. In this I am able to get data in firebase collection but it is not query that data in recycler view.

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(&quot;&quot;)) {
Toast.makeText(Comments.this, &quot;Comment can&#39;t be empty&quot;, Toast.LENGTH_SHORT).show();
} else {
String commentText = addcommenttext.getText().toString();
CollectionReference commentref = FirebaseFirestore.getInstance() .collection(&quot;CommentDetails&quot;);
commentref.add(new comment_list(commentText));
FirebaseFirestore fbfs = FirebaseFirestore.getInstance();
CollectionReference commentrefs = fbfs.collection(&quot;CommentDetails&quot;);
Query query = commentrefs;
FirestoreRecyclerOptions&lt;comment_list&gt; options = new FirestoreRecyclerOptions.Builder&lt;comment_list&gt;()
.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, &quot;Commented&quot;, Toast.LENGTH_SHORT).show();
}
}
});
}

答案1

得分: 2

首先,让我们重新配置你的 Comments 活动类。建议在 onCreate 方法中初始化回收适配器,而不是在重写的 onClick 方法中。根据当前的设置,每次触发 onClick 监听器时都会初始化一个新的 comment_adapter。最好我们只设置一个。以下是在更改后的情况下的情况(我已添加了注释以增加清晰度):

注意:我已经根据 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);

        FirebaseFirestore.setLoggingEnabled(true);

        db = FirebaseFirestore.getInstance();
        Query query = db.collection("CommentDetails").orderBy("timestamp").limit(50);

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

        commentAdapter = new CommentAdapter(options);
        commentRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        commentRecyclerView.setAdapter(commentAdapter);

        addCommentButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                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 的自述文件 对你会有很大帮助。

需要注意的是,我还将你的数据模型从 comment_list 重命名为 Comment。这样做的原因是,该类的实例仅存储一个评论的状态,而不是评论列表。在调试代码时,这可能会引起混淆。在使用 FirebaseUI 的情况下,实际的评论列表(comments list),它绑定到你的回收视图,由 FirebaseUI 代码为你构建,形式是一系列 Comment 类的实例。

为了清楚地理解这是如何实现的,可能有必要花几个小时来实现一个不连接到 Firestore 的简单回收视图和适配器。这样可以更好地理解 FirebaseUI 如何完成工作。有关此方面的文档在 此处

最后 - 这是对 comment_list 类的替代方案:

public class Comment {

    String comment;
    @ServerTimestamp Date timestamp;

    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"。这是一个常见的错误。如果只看到一个回收项被渲染,请首先检查这一点。

英文:

First of all, let's reconfigure your Comments activity class. It would be recommended to initialise the recycle adapter in your onCreate method and not in the overridden onClick method. With the current set up, a new comment_adapter is initialised every time the onClick listener is triggered. It's best that we set-up only one. Here's how things look after the changes (I've added comments for clarity):

NOTE: I have renamed classes, variables and methods to use java and android conventions for clarity. Learning these will help you a lot in being able to read others code and save you a lot of headaches with your own code.

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(&quot;CommentDetails&quot;).orderBy(&quot;timestamp&quot;).limit(50);
FirestoreRecyclerOptions&lt;Comment&gt; options = new FirestoreRecyclerOptions.Builder&lt;Comment&gt;()
.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, &quot;Comment can&#39;t be empty&quot;, Toast.LENGTH_SHORT).show();
} else {
String commentText = commentEditText.getText().toString();
CollectionReference commentColRef = FirebaseFirestore.getInstance().collection(&quot;CommentDetails&quot;);
commentColRef.add(new Comment(commentText));
Toast.makeText(CommentsActivity.this, &quot;Commented&quot;, Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
protected void onStart() {
super.onStart();
commentAdapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
commentAdapter.stopListening();
}
}

You will notice the addition of two new methods: onStart and onStop. Within these methods we start and stop the query listeners attached to the FirestoreRecyclerAdapter. It will be really helpful to refer to the FirebaseUI for Cloud Firestore read-me.

It is important to note in the code above I also renamed your data model from comment_list to Comment. The reason for this, is that an instance of this class only stores the state of one comment. It does not store a list of comments. I think it might cause confusion when you are trying to debug your code. In the case of using FirebaseUI, the actual list of comments (the comments list) which is bound to your recycle view is built for you by the FirebaseUI code, in the form of an array of Comment class instances.

In order to understand clearly how this is done, it might be useful to spend a couple of hours implementing a simple recycle view and adapter that is not connected to Firestore. That way a greater understanding as to how FirebaseUI is doing things can be developed. There are docs on that here.

Finally - here is a replacement to the 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;
}

The only difference here is there is a zero-args (no argument) constructor, which is required by firestore.

A word to the wise - I haven't seen your view model item layout (comment_recycler_dsign), but just check that the root layout does not have a height of "match_parent". This is a common mistake. It is a good idea to check this first if you see only one recycle item being rendered.

答案2

得分: 0

将监听器放置在代码中,Firebase 会在上传完成后自动调用该监听器。

firestore.collection("").add(Any()).addOnCompleteListener { 
    // 在此处完成所有操作
}
英文:

Place a listener
fire base will automatically call once the upload is complete

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

huangapple
  • 本文由 发表于 2020年10月7日 13:51:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/64237964.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定