Подождите, пока данные Firestore будут получены для запуска действия - PullRequest
0 голосов
/ 01 июня 2018

Я составил список объектов POJO, которые получают значения из моей базы данных Cloud Firestore.Этот список сам по себе является классом, имеющим в виду получение атрибутов каждый раз, когда я создаю новый список.Дело в том, что список заполняется не при создании, а через некоторое время.Я пытался добавить циклы, задачи, ожидания, но не получил желаемый результат.Вот как я получаю свои данные удовлетворительно:

private void retrieveData(){
        reference = firestore.collection("attractions");
        reference.addSnapshotListener(new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots,
                                @Nullable FirebaseFirestoreException e) {
                attractionList.clear();
                for (DocumentSnapshot snapshot : queryDocumentSnapshots) {
                    Attraction attraction = snapshot.toObject(Attraction.class);
                    addAttractions(attraction);
                }
            }
        });
    }

Я получаю данные каждый раз, когда создаю новый объект:

public AttractionList() {
        firestore.setFirestoreSettings(settings);
        reference = firestore.collection("attractions");
        attractionList = new ArrayList<>();
        retrieveData();
    }

Затем, если я проверяю размер списка в моей активности наcreate:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_attraction);
        Toolbar toolbar = findViewById(R.id.tb_attraction);
        setSupportActionBar(toolbar);

        //Creating POJO List and retrieving data
        attractionList = new AttractionList();
        Log.e("List Size: ", ""+attractionList.getAttractionList().size());
        //List Size: 0
    }

Но если я использую то же время Журнала после, в любой кнопке:

@Override
    public void onBackPressed(){
        Log.e("List Size: ", ""+attractionList.getAttractionList().size());
        //List Size: 16
    }

На самом деле я не хочу получать данные в каждой отдельной Деятельности или создании намеренийпривести объект между действиями.Есть ли способ, как я мог это исправить?

PS: Это мой первый пост.Извините, если я не сделал это правильно.Большое спасибо.

1 Ответ

0 голосов
/ 04 июня 2018

Вы не можете использовать что-то, что еще не было загружено.Firestore загружает данные asynchronously, так как для этого может потребоваться некоторое время.В зависимости от скорости вашего соединения и состояния, эти данные могут занять от нескольких сотен миллисекунд до нескольких секунд.Если вы хотите передать список объектов типа Attraction другому методу, просто вызовите этот метод внутри метода onSuccess() и передайте этот список в качестве аргумента.Таким образом, быстрое исправление будет следующим:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference attractionsRef = rootRef.collection("attractions");

attractionsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            List<Attraction> attractionsList = new ArrayList<>();
            for (QueryDocumentSnapshot document : task.getResult()) {
                Attraction attraction = document.toObject(Attraction.class);
                attractionsList.add(attraction);
            }
            methodToProcessTheList(attractionsList);
        }
    }
});

Помните, что метод onSuccess() имеет асинхронное поведение, что означает, что он вызывается еще до того, как вы получаете данные из своей базы данных.Если вы хотите использовать attractionsList вне этого метода, вам нужно создать свой собственный callback.Для этого сначала нужно создать интерфейс, подобный следующему:

public interface MyCallback {
    void onCallback(List<Attraction> attractionsList);
}

Затем вам нужно создать метод, который фактически получает данные из базы данных.Этот метод должен выглядеть следующим образом:

public void readData(MyCallback myCallback) {
    attractionsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                List<Attraction> attractionsList = new ArrayList<>();
                for (QueryDocumentSnapshot document : task.getResult()) {
                    Attraction attraction = snapshot.toObject(Attraction.class);
                    attractionsList.add(attraction);
                }
                myCallback.onCallback(attractionsList);
            }
        }
    });
}

В конце просто вызовите метод readData() и передайте экземпляр интерфейса MyCallback в качестве аргумента, где бы он вам ни понадобился, например:

readData(new MyCallback() {
    @Override
    public void onCallback(List<Attraction> attractionsList) {
        //Do what you need to do with your list
    }
});

Это единственный способ использовать этот объект attractionsList вне метода onSuccess().Для получения дополнительной информации, вы также можете посмотреть это видео .

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