Есть ли способ получить данные из firebase, где находится код? В настоящее время у меня есть valueEventListeners, но все они запускаются после кода под ними, что делает следующий код недействительным. Я хочу иметь возможность получить значение именно там, где находится код, а не позже.
Пока в сети ничего по этому поводу не нашел.
Хороший пример моих проблем в коде:
public void onItemClick(AdapterView<?> l, View v, final int position, long id) {
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
final String uid = user.getUid();
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
cCESnapshot = dataSnapshot.child(uid).child("currChallenges").child(challengeList.get(position));
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Intent intent = new Intent();
intent.setClass(this, ChallengeView.class);
intent.putExtra("snapshot", cCESnapshot.toString());
intent.putExtra("name", challengeList.get(position));
startActivity(intent);
}
cCESnapshot имеет значение null, так как намерение запускается перед valueEventListener.
Намерение работает нормально прямо сейчас, если только, поместив его в другой поток, вызов Android не будет запущен первым.
onDataChange()
является асинхронным, поэтому единственный способ использовать полученные данные — внутри onDataChange()
, например:
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
cCESnapshot = dataSnapshot.child(uid).child("currChallenges").child(challengeList.get(position));
Intent intent = new Intent();
intent.setClass(this, ChallengeView.class);
intent.putExtra("snapshot", cCESnapshot.toString());
intent.putExtra("name", challengeList.get(position));
startActivity(intent);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Это асинхронная операция, когда данные поступят, будет запущен обратный вызов onDataChange
. Ваш код startActivty
будет выполняться последовательно, поэтому вы не получите значения в cCESnapshot
.
Переместите код startActivity
внутрь слушателя.
Но будь осторожен, потому что каждый раз, когда будет вызываться прослушиватель кликов onItemClick
, вы будете добавлять прослушиватель событий значения. Таким образом, у вас будет несколько вызовов onDataChange
при каждом клике и, следовательно, несколько startActivities
.
Вместо этого я рекомендую использовать addListenerForSingleValueEvent
, который будет срабатывать только после однократного изменения данных.
Вы должны поместить создание намерения и startActivity в
onDataChange
. Вы не можете запускать сетевые запросы в основном потоке/синхронизированном.