В моем действии, где я собираю все данные от определенного пользователя и отображаю их, этот метод 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 (). Хотя это тоже никогда не срабатывало, так что теперь я совершенно запутался.
Любая помощь приветствуется, и, пожалуйста, отправьте ссылки на документацию, которую я мог бы прочитать, чтобы углубить мое понимание, связанное с этой темой.




Причина этой проблемы уже описана вами в вопросе, поэтому один из способов решения этой проблемы следующий:
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");
}
});
Да, определенно, поскольку onDataChange будет выполняться, когда вы получите данные. Кроме того, вы можете проверить dataSnapshot.exists и! = Null.
Перед тем, как лечь спать, мне просто нужно было попробовать, и это сработало просто потрясающе. Большое вам спасибо, я все еще новичок в разработке Android, и потоки все еще меня очень сбивают с толку. Если вы не возражаете, не могли бы вы объяснить немного подробнее, как это работает на самом деле, и что отличает ваше решение от моего? Я пытаюсь понять, что заставляет мое старое "решение" всегда полностью возвращать ложный профиль.
Обратитесь к academy.realm.io/posts/android-threading-background-tasks
но всегда ли такое решение будет гарантировать, что я получу данные, прежде чем пытаться использовать условные операторы? Если нет, мне нужно найти способ остановить основной поток, пока я не получу ответ. Еще раз спасибо за информацию, и я обязательно попробую!