почему мой ArrayList пуст, хотя в базе данных firebase есть дочерние записи - PullRequest
0 голосов
/ 06 февраля 2020

Я пытаюсь получить пользовательские данные из базы данных Firebase в реальном времени, datasnapshot содержит дочерние элементы и данные, но когда я пытаюсь поместить их в массив, массив становится пустым. Я создал пользовательский класс, который содержит свойства, совпадающие со свойствами в firebase, перегруженными конструкторами и некоторыми методами. Он не расширяет ни один класс, хотя, как я знаю, он не будет работать с извлечением данных из Firebase.

private List<user> usersList = new ArrayList<>();
private DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
private DatabaseReference ref = databaseReference.child("Users");

public List<user> getUsers(){
    ref.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if(dataSnapshot.exists()){
                Log.i("users", String.valueOf(dataSnapshot.getChildrenCount()));

                for(DataSnapshot child: dataSnapshot.getChildren()){
                    user userRetrieved = child.getValue(user.class);
                    Log.d("USER before array", userRetrieved.getUserName());
                    usersList.add(userRetrieved);
                    for(int i = 0;i < usersList.size(); i++){
                        Log.d("USER", usersList.get(i).getUserName());
                    }

                }
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.i("ERROR", databaseError.getMessage());
        }
    });

    return usersList;
}

Все отзывы приветствуются.

Ответы [ 2 ]

0 голосов
/ 08 февраля 2020

Я понял, должен был убедиться, что мой класс соответствует объекту, возвращаемому из БД. Сначала я должен был сделать мой класс пользователя реализуемым для сериализации и добавить @PropertyName(), а также убедиться, что все имена свойств точно совпадают с тем, что было в Firebase.

 public List<User> getUsers(){
    ref.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            try{
                for(DataSnapshot childSnapshot: dataSnapshot.getChildren()){
                    User User = childSnapshot.getValue(User.class);
                    usersList.add(User);
                        User[] UserArray = new User[usersList.size()];
                        UserArray = usersList.toArray(UserArray);
                    for(int i = 0;i < usersList.size(); i++){
                        Log.d("NAME", UserArray[i].getUserName());
                    }


                }
            }catch (Exception e){
                Log.d("Error in the try", e.getMessage());
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.i("ERROR", databaseError.getMessage());
        }
    });

    return usersList;
}
0 голосов
/ 06 февраля 2020

API Firebase являются асинхронными. addListenerForSingleValueEvent немедленно возвращается, и обратный вызов, который вы передаете ему, выполняется спустя некоторое время после завершения запроса. Нет гарантии, как быстро это произойдет. Между тем, ваша функция возвращает изначально пустой список. Возможно, у вас есть код для его чтения с предположением, что запрос уже завершен, а на самом деле его нет.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...