Я не могу добавить элементы в HashMap после запроса их от firebase android - PullRequest
0 голосов
/ 29 февраля 2020

Моя цель - показать автора и дату последнего опубликованного сообщения с указанием c topi c.

У меня есть две коллекции: forum_topics и forum_posts. Я перебираю все forum_topics и получаю нужные данные, помещаю их в topicData HashMap, затем сохраняю HashMap в ArrayList и отображаю его через ListView, это прекрасно работает.

Но когда я хочу go через forum_posts (этот запрос вложен в запрос forum_topics), чтобы получить последнего автора сообщения и дату, когда я получаю данные, но не могу поместить их в HashMap topicData. Запрос в порядке, потому что он получает последнего автора и публикацию в виде логов, но они не помещаются в HashMap. Я не знаю, в чем проблема.

В коде есть комментарий указывая на запрос, который получает данные, но не добавляет данные в хэш-карту.

Ниже приведен код

@Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_forum);
    addTopic = findViewById(R.id.addNewTopicBtn);
    fStore = FirebaseFirestore.getInstance();
    empty = findViewById(R.id.empty);


    final ArrayList<Map> forumTopics = new ArrayList<>();

    final ListAdapter forumAdapter = new ForumAdapter(this, forumTopics);
    ListView forumListView = findViewById(R.id.ForumListView);
    forumListView.setEmptyView(empty);
    forumListView.setAdapter(forumAdapter);


    fStore.collection("forum_topics")
            .orderBy("date_published", Query.Direction.ASCENDING)
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            final Map<String, Object> topicData = new HashMap<>();
                            // getting topic name and putting it to the topicData HashMap
                            topicData.put("topic_name", document.getId());
                            // getting topic author and putting it to the topicData HashMap
                            topicData.put("author", document.getString("author"));
                            // getting the date_published timestamp
                            Date date_published = document.getTimestamp("date_published").toDate();
                            // formatting the date to the desired 24hr format and putting it into the HashMap
                            topicData.put("date_published", DateFormat.format("dd-MM-yyyy hh:mm:ss", date_published).toString());
                            // getting the post_num and putting it to the topicData HashMap
                            topicData.put("post_num", document.get("post_num").toString());
                            Log.d(TAG, "Got the topic with name: " + document.getId());

// below is the problematic query that doesn't add data to HashMap
                            fStore.collection("forum_posts")
                                    .whereEqualTo("topic_name", document.getId())
                                    .orderBy("date_published", Query.Direction.DESCENDING)
                                    .limit(1)
                                    .get()
                                    .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                        @Override
                                        public void onComplete(@NonNull Task<QuerySnapshot> task) {
                                            if (task.isSuccessful()) {
                                                for (QueryDocumentSnapshot post : task.getResult()) {
                                                    Log.d(TAG, "got the last author " + post.getString("author"));
                                                    topicData.put("last_post_author", post.getString("author"));
                                                    Date date_published = post.getTimestamp("date_published").toDate();
                                                    String last_date_published = DateFormat.format("dd-MM-yyyy hh:mm:ss", date_published).toString();
                                                    topicData.put("last_post_published", last_date_published);
                                                    Log.d(TAG, "got the last post " + last_date_published);
                                                }
                                            } else {
                                                Log.d(TAG, "Error getting documents: ", task.getException());
                                            }
                                        }
                                    });

                            forumTopics.add(topicData);
                        }
                        // notifying the forumAdapter with data change
                        ((ArrayAdapter) forumAdapter).notifyDataSetChanged();
                    } else {
                        Log.d(TAG, "Error getting documents: ", task.getException());
                    }
                }
            });

    forumListView.setOnItemClickListener(
            new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Map topicData = (Map) parent.getItemAtPosition(position);
                    String topic = (String) topicData.get("topic_name");
                    Intent intent = new Intent(Forum.this, ForumTopic.class);
                    intent.putExtra("topic_name", topic);
                    startActivity(intent);
                    finish();
                }
            }
    );

    addTopic.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(Forum.this, ForumPostTopic.class));
        }
    });

}

Я пробовал несколько вещей, выполняя запрос вне запроса forum_topics перебирая ArrayList и затем помещая элементы, я помещал запрос в отдельный метод, я даже пытался создать другой ArrayList, перебирающий первый, получать данные из него, возвращать его в другой HashMap и добавлять его в новый ArrayList и обновлять адаптер, но все они вышли из строя.

Может быть, я могу получить нужные данные из коллекции forum_posts другим способом, не запрашивая?

Буду благодарен за любые полезные советы. Я надеюсь, что вопрос теперь упрощен, так как мой предыдущий был закрыт.

Журналы:

D/TAG: Got the topic with name: Some new topic in here
D/TAG: Got the topic with name: This is a new topic
D/TAG: Got the topic with name: 123
D/TAG: Got the topic with name: new topic
I/zygote: Do full code cache collection, code=124KB, data=79KB
I/zygote: After code cache collection, code=123KB, data=48KB
I/zygote: Do partial code cache collection, code=123KB, data=47KB
I/zygote: After code cache collection, code=123KB, data=47KB
    Increasing code cache capacity to 512KB
D/TAG: got the last author Jo Do
D/TAG: got the last post 26-02-2020 10:42:46
    got the last author Jo Do
D/TAG: got the last post 26-02-2020 02:29:16
    got the last author Jo Do
D/TAG: got the last post 26-02-2020 11:01:25
D/TAG: got the last author Jo Do
D/TAG: got the last post 28-02-2020 11:19:34

Скриншот из firebase:

forum_topics: forum_topics

forum_posts: отсюда я получаю данные выделены красным, но не могут быть помещены в HashMap enter image description here

Снимок экрана с устройства:

enter image description here

1 Ответ

1 голос
/ 29 февраля 2020

Мне удалось решить эту проблему, уведомив forumAdapter после получения обратного вызова от onComplete во втором запросе.

При отладке приложения я увидел, что код во втором запросе выполняется после завершения первого запроса. , Похоже, запрос был отложен.

Таким образом, данные фактически были добавлены в HashMap, но адаптер не знал о новых добавленных данных, поэтому его нужно было уведомить дважды, я думал, что этого будет достаточно после Основной запрос, очевидно, должен быть уведомлен каждый раз при изменении набора данных, это был очень ценный урок, и я понял, что решение было простым.

Код ниже (я публикую только код для запроса, который мне показался не работал):

fStore.collection("forum_posts")
        .whereEqualTo("topic_name", document.getId())
        .orderBy("date_published", Query.Direction.DESCENDING)
        .limit(1)
        .get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    for (QueryDocumentSnapshot post : task.getResult()) {
                        Log.d(TAG, "got the last author " + post.getString("author"));
                        topicData.put("last_post_author", post.getString("author"));
                        Date date_published = post.getTimestamp("date_published").toDate();
                        String last_date_published = DateFormat.format("dd-MM-yyyy hh:mm:ss", date_published).toString();
                        topicData.put("last_post_published", last_date_published);
                        Log.d(TAG, "got the last post " + last_date_published);
                    }
                } else {
                    Log.d(TAG, "Error getting documents: ", task.getException());
                }
                // notifying the forumAdapter with data change
                ((ArrayAdapter) forumAdapter).notifyDataSetChanged();
            }
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...