Как получить данные из ValueEventListener Firebase - PullRequest
0 голосов
/ 18 мая 2018

У меня есть приложение для Android, использующее Google Firebase.

Мне нужно загрузить изображение со случайным идентификатором.

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

    Random rand = new Random();
    DatabaseReference amountRef = dbref.child("amount");
    amountRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            amount = dataSnapshot.getValue(Long.class);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    long random = rand.nextLong() % amount + 1;

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

long random = rand.nextLong() % amount + 1;

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

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Вы не можете вернуть что-то, что еще не было загружено.Другими словами, вы не можете просто использовать объект amount вне метода onDataChange(), поскольку он всегда будет null из-за асинхронного поведения этого метода.Это означает, что к тому времени, когда вы пытаетесь использовать этот результат вне этого метода, данные еще не закончили загрузку из базы данных, и поэтому они недоступны.

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

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

Вы можете использовать текстовое представление с visibility = lost (так, чтобы оно не было видно в вашей активности). Используйте setText (), чтобы установить для него значение.После выхода из Value Event Listener используйте getText (), чтобы получить ваше значение.Это просто трюк, который очень помогает.Ваш код будет выглядеть примерно так:

 TextView textview=findViewById(R.id.textView);
Random rand = new Random();
    DatabaseReference amountRef = dbref.child("amount");
    amountRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            amount = dataSnapshot.getValue(Long.class);
textview.setText(""+amount);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
int amount=Integer.parseInt(textview.getText());
    long random = rand.nextLong() % amount + 1;

Надеюсь, это поможет:)

0 голосов
/ 18 мая 2018

Вы должны использовать это следующим образом

Random rand = new Random();
    DatabaseReference amountRef = dbref.child("amount");
    amountRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            amount = dataSnapshot.getValue(Long.class);
            // add Random rand = new Random(); here if you need new random objects everytime.
            long random = rand.nextLong() % amount + 1;
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

Вы пытаетесь получить доступ к данным из асинхронной функции, поэтому, если вы попытаетесь получить доступ после переменной, она, возможно, не завершила свою работу, поэтомуможет вернуть null, это не точно, и поэтому вы должны получить к нему доступ внутри.

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