Почему firebase не может запрашивать данные из коллекции в представлении recycler?

#java #android #database #firebase #comments

#java #Android #База данных #firebase #Комментарии

Вопрос:

Я могу получить данные в коллекции firebase, но он не запрашивает эти данные в представлении recycler. 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, но они не запрашивают эти данные в представлении recycler.

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

                }
            }


    });

}
  

Комментарии:

1. Пожалуйста, опубликуйте свою структуру базы данных

2. Данные в вашей базе данных

3. ваша средняя коллекция в облачном firestore?

4. Пожалуйста, отредактируйте свой вопрос и добавьте свою структуру базы данных в виде скриншота. Пожалуйста, ответьте с помощью @AlexMamo

5. @AlexMamo я сделал, пожалуйста, проверьте

Ответ №1:

Прежде всего, давайте перенастроим ваш класс активности комментариев. Было бы рекомендовано инициализировать адаптер recycle в вашем onCreate методе, а не в переопределенном onClick методе. При текущей настройке новый comment_adapter инициализируется каждый раз, когда запускается прослушиватель onClick. Лучше всего, чтобы мы настроили только один. Вот как все выглядит после изменений (я добавил комментарии для ясности):

ПРИМЕЧАНИЕ: я переименовал классы, переменные и методы, чтобы использовать соглашения 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();
    }
}
  

Вы заметите добавление двух новых методов: onStart и onStop . В рамках этих методов мы запускаем и останавливаем прослушиватели запросов, подключенные к FirestoreRecyclerAdapter . Будет очень полезно обратиться к FirebaseUI для чтения в облачном Firestore.

Важно отметить, что в приведенном выше коде я также переименовал вашу модель данных из comment_list в Comment . Причина этого в том, что экземпляр этого класса хранит состояние только одного комментария. Он не хранит список комментариев. Я думаю, что это может вызвать путаницу, когда вы пытаетесь отладить свой код. В случае использования FirebaseUI фактический список комментариев (список комментариев), который привязан к вашему представлению recycle, создается для вас кодом FirebaseUI в виде массива экземпляров класса комментариев.

Чтобы четко понять, как это делается, может быть полезно потратить пару часов на реализацию простого представления recycle и адаптера, который не подключен к Firestore. Таким образом, можно получить более глубокое понимание того, как FirebaseUI работает. Здесь есть документы по этому вопросу.

Наконец, вот замена классу 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». Это распространенная ошибка. Рекомендуется сначала проверить это, если вы видите, что отображается только один элемент recycle.

Комментарии:

1. Это работает, спасибо. Не могли бы вы сказать мне, как я могу заказать запрос, например, если я оставлю комментарий, тогда он появится сверху, а затем появится сверху?

2. Возникает проблема, связанная с тем, что каждый комментарий отображается в каждом сообщении, а не в одном сообщении

3. @Harnoor Попробуйте добавить поле «timestamp» в класс комментариев. Каждый раз, когда делается комментарий, публикуйте временную метку вместе с ним. Затем отредактируйте запрос firebase, чтобы Query query = db.collection("chats").orderBy("timestamp").limit(50); посмотреть ( github.com/firebase/FirebaseUI-Android/tree/master /… ). Пример реализации идеально подходит для того, что вы пытаетесь сделать. (= Удачи!

4. Не работает должным образом, комментарий размещен неточно, означает, что комментарий не размещен в соответствии с самым новым первым появлением

5. @Harnoor Вот рабочая реализация, на которую вы тоже можете сослаться. (: ( github.com/michael-lundie/stackoverflow_temp ) Я также обновил код в приведенном выше ответе с помощью функции временной метки.

Ответ №2:

Поместите слушателя, который fire base автоматически вызовет после завершения загрузки

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

Комментарии:

1. Операционная система Harnoor использует FirebaseUI и FirestoreRecyclerAdapter . В этом случае слушатели обрабатываются через адаптер, вызывая его startListening() и stopListening() методы соответственно. Однако, конечно, это потребуется в случае использования вашей собственной реализации пользовательского адаптера.