I am able to get data in firebase collection but it does not query that data in recycler view. Recyclerview does not showing anything
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<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 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("")) {
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();
}
}
});
}
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("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();
}
}
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.