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

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

public class UserStore {
    private Firebase rootRef_; 
    private UserDetails userDetails;

    public UserStore() {
         rootRef_ = new Firebase("https://<FIREBASE-APP>.firebaseio.com/");
    }

    public UserDetails getUserDetails(String mailId) {
        mailId = mailId.toLowerCase().replace(".", ",");
        rootRef_.child("users/" + mailId).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if (dataSnapshot != null) {
                    System.out.println("user data snapshot: " + dataSnapshot.toString());
                    UserStore.this.userDetails = dataSnapshot.getValue(UserDetails.class);
                } else {
                    System.out.println("data snapshot is null!!");
                }
            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });
        return userDetails;
    }
 }

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

В любом случае, в котором я могу получить ответ в реальном времени?


person Rana    schedule 23.05.2016    source источник
comment
Что вы имеете в виду под реальным временем? Конечно, получение данных из любой удаленной базы данных займет некоторое время. У вас может быть прослушиватель потока, чтобы при извлечении данных у вас был обратный вызов функции.   -  person Reaz Murshed    schedule 23.05.2016
comment
Я прав, вы используете прослушиватель только для загрузки данных один раз? Если да, лучше использовать какой-нибудь API синхронизации.   -  person Victor Sorokin    schedule 23.05.2016
comment
да, очевидно, что каждый вызов требует времени, но я имел в виду, что это занимает значительное время, даже несмотря на то, что у меня очень маленькая (10 пар ключ-значение) база данных. Это занимает более 7-8 секунд. Да, у меня есть слушатель, но проблема в том, что перед получением события основной поток завершается. Поэтому я хотел знать, есть ли способ приостановить основной поток на точное время, когда наступает событие, кроме сна, или сон - единственный способ. Если я буду использовать здесь сон, то мне нужно указать жестко закодированное значение, которое может быть больше, чем фактическое время выборки.   -  person Rana    schedule 23.05.2016
comment
да @Victor, я хочу загрузить данные только один раз. Вы правы насчет API синхронизации. Я также ищу синхронизацию Apis, но мне ничего не известно в Firebase. Не могли бы вы дать ссылку, если у вас есть ??   -  person Rana    schedule 23.05.2016
comment
Извините, у вас нет опыта работы с Firebase. Этот stackoverflow.com/a/11588115/162634 подразумевает, что API слушателей является первым выбором. Итак, я не вижу реальной проблемы с вашим кодом.   -  person Victor Sorokin    schedule 23.05.2016


Ответы (1)


Вы возвращаете UserDetail до завершения обратного вызова. Это действительно касается организации асинхронного кода, а не Firebase.

public void getUserDetails(String mailId) {
        mailId = mailId.toLowerCase().replace(".", ",");
        rootRef_.child("users/" + mailId).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if (dataSnapshot != null) {
                    System.out.println("user data snapshot: " + dataSnapshot.toString());
                    UserDetail userDetails = dataSnapshot.getValue(UserDetails.class);
                    //DO SOMETHING WITH USER DETAILS HERE!
                } else {
                    System.out.println("data snapshot is null!!");
                }
            }

            @Override
            public void onCancelled(FirebaseError firebaseError) {

            }
        });
        //DONT RETURN USER DETAILS HERE
    }

Для получения дополнительной информации см. AsyncTask или RxJava с Android

person Max Alexander    schedule 24.05.2016