Мой метод databaseReference valueEventListener onDataChange не срабатывает

В моем действии, где я собираю все данные от определенного пользователя и отображаю их, этот метод onDataChange запускается правильно, отображая данные идеально.

final User user = new User();

     databaseReference.addValueEventListener(new ValueEventListener()
     {
         @Override
         public void onDataChange(@NonNull DataSnapshot dataSnapshot)
         {
             user.setFirstName(dataSnapshot.getValue(User.class).getFirstName());
             view_profile_firstName.setText(user.getFirstName().toString());

             user.setLastName(dataSnapshot.getValue(User.class).getLastName());
             view_profile_lastName.setText(user.getLastName().toString());

             user.setEmail(dataSnapshot.getValue(User.class).getEmail());
             view_profile_email.setText(user.getEmail().toString());

             user.setAge(dataSnapshot.getValue(User.class).getAge());
             view_profile_age.setText(Integer.toString(user.getAge()));

             user.setGender(dataSnapshot.getValue(User.class).getGender());
             view_profile_gender.setText(user.getGender());

             user.setProfileComplete(dataSnapshot.getValue(User.class).getProfileComplete());
             view_profile_profileComplete.setText(String.valueOf(user.getProfileComplete()));

         }

         @Override
         public void onCancelled(@NonNull DatabaseError databaseError)
         {

         }
     });

Хотя сейчас я пытаюсь проверить, истинно ли profileComplete при входе текущего пользователя. Я хочу, чтобы это работало, когда пользователь регистрируется для учетной записи, его данные сохраняются в виде пустых строк, а для profileComplete установлено значение false. После того, как все данные будут заполнены и он сохранит свой профиль, для параметра profileComplete будет установлено значение true. Причина этого в том, что когда они снова входят в систему после закрытия приложения, я хочу, чтобы оно выводило их на главный экран вместо того, чтобы запускать их обратно через создание профиля.

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

firebaseAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>()
    {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task)
        {
            if (task.isSuccessful())
            {
                final User user = new User();

                Toast.makeText(MainActivity.this, "Successful login!", Toast.LENGTH_SHORT).show();

                //Dialog related to alerting the user we are logging them in
                progressDialog.cancel();

                //Check if logging in user has completed profile or not.
                databaseReference = firebaseDatabase.getReference("Users/" + firebaseAuth.getInstance().getCurrentUser().getUid());
                databaseReference.addValueEventListener(new ValueEventListener()
                {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot)
                    {
                        user.setProfileComplete(dataSnapshot.getValue(User.class).getProfileComplete());
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError)
                    {
                        Log.d("MainActivity", "COULD NOT RECIEVE PROFILECOMPLETE FROM DATABASE");
                    }
                });

                //The profileComplete method returns TRUE, so we can skip the profile creation.
                if (user.getProfileComplete())
                {
                    Intent intent = new Intent(MainActivity.this, ViewProfileActivity.class);
                    startActivity(intent);
                }

                //the profileComplete method returns FALSE, we must send the user to the profile creation.
                else
                {
                    Intent intent = new Intent(MainActivity.this, ProfileActivity.class);
                    startActivity(intent);
                }

Я просматривал stackoverflow примерно от 45 минут до часа, просматривая всевозможные решения, такие как попытка использовать асинхронную обработку.

Моя гипотеза заключается в том, что, поскольку все это выполняется в основном потоке, метод onDataChange не получает данные вовремя, которые будут использоваться для оператора if. Хотя, чтобы попытаться решить эту проблему, я поставил

databaseReference.addValueEventListener(new ValueEventListener()

В цикле while с логической переменной, установленной в false, которая будет установлена ​​в true только после запуска метода onDataChanged (). Хотя это тоже никогда не срабатывало, так что теперь я совершенно запутался.

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
362
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Причина этой проблемы уже описана вами в вопросе, поэтому один из способов решения этой проблемы следующий:

databaseReference = firebaseDatabase.getReference("Users/" + firebaseAuth.getInstance().getCurrentUser().getUid());
databaseReference.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

        user.setProfileComplete(dataSnapshot.getValue(User.class).getProfileComplete());

        //The profileComplete method returns TRUE, so we can skip the profile creation.
        if (user.getProfileComplete()) {
            Intent intent = new Intent(MainActivity.this, ViewProfileActivity.class);
            startActivity(intent);
        }

        //the profileComplete method returns FALSE, we must send the user to the profile creation.
        else {
            Intent intent = new Intent(MainActivity.this, ProfileActivity.class);
            startActivity(intent);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d("MainActivity", "COULD NOT RECIEVE PROFILECOMPLETE FROM DATABASE");
    }
});

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

user8826306 06.08.2018 05:48

Да, определенно, поскольку onDataChange будет выполняться, когда вы получите данные. Кроме того, вы можете проверить dataSnapshot.exists и! = Null.

Raj 06.08.2018 05:50

Перед тем, как лечь спать, мне просто нужно было попробовать, и это сработало просто потрясающе. Большое вам спасибо, я все еще новичок в разработке Android, и потоки все еще меня очень сбивают с толку. Если вы не возражаете, не могли бы вы объяснить немного подробнее, как это работает на самом деле, и что отличает ваше решение от моего? Я пытаюсь понять, что заставляет мое старое "решение" всегда полностью возвращать ложный профиль.

user8826306 06.08.2018 06:54

Обратитесь к academy.realm.io/posts/android-threading-background-tasks

Raj 06.08.2018 08:08

Другие вопросы по теме