Так что у меня есть база данных Firebase в реальном времени, в которой есть ребенок, с детьми под ним. Я хочу перебрать ребенка и добавить ключи детей в список.
Это то, что я делаю:
public ArrayList<String> debateKeys() {
debatesChildren.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
tempItems.add(postSnapshot.getKey());
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
return tempItems;
}
Когда я использую отладчик, он показывает, что tempItems
ничего не возвращает, а onDataChange
даже не выполняется, что означает, что он даже не запускает цикл for.
Как пройти через детей и добавить их ключи в список?
addValueEventListener() является асинхронным и возвращается немедленно. Прослушиватель, которого вы передали ему, будет вызван через некоторое время, когда результаты станут известны. Это означает, что вы возвращаете изначально пустые templates
. Кто бы ни держался за templates
может удивиться, если и когда содержимое обновится в непредсказуемое время после возврата вашей функции. Мало того, содержимое будет продолжать меняться со временем, так как ваш слушатель будет вызываться при каждом изменении местоположения, представленного debatesChildren
. Это действительно ужасная ситуация.
Прежде всего, если вам нужен доступ к данным только один раз, вы должны использовать addListenerForSingleValueEvent(), чтобы гарантировать, что ваш слушатель вызывается только один раз.
Во-вторых, вы не должны пытаться превращать асинхронный вызов в синхронный вызов. Некоторым другим частям вашего кода нужны результаты запроса к базе данных, которые они должны получать через обратный вызов, а не через возвращаемое значение функции. Вам нужно будет выяснить, как вы хотите выполнять асинхронное программирование в своем приложении, и подключить его по своему усмотрению.