#flutter #asynchronous #firebase-realtime-database #async-await #future
#flutter #асинхронный #firebase-база данных в реальном времени #асинхронный -ожидание #будущее
Вопрос:
У меня есть следующий метод:
Future<List<Job>> getUserJobs() async {
Query query = _firebaseDatabase
.reference()
.child("jobs")
.child(_firebaseAuth.currentUser.uid)
.orderByKey();
List<Job> userJobs = [];
if (query == null) {
return userJobs;
}
query.onValue.listen((event) {
Map<dynamic, dynamic> values = event.snapshot.value;
values.forEach((key, value) {
userJobs.add(Job.fromJson(key, Map.from(value)));
});
});
return userJobs;
}
Я хочу получить этот ответ в другом классе, однако список, возвращаемый вышеуказанным методом, всегда равен [] . Я проверил, и список пользовательских заданий действительно заполнен, но оператор return выполняется раньше.
Структура базы данных такова: коллекция заданий имеет идентификаторы пользователей, и для каждого идентификатора пользователя у меня есть несколько ключей заданий (каждый со своими данными задания).
Ответ №1:
Попробуйте это:
Future<List<Job>> getUserJobs() async {
List<Job> userJobs = [];
// Query query =
await _firebaseDatabase
.reference()
.child("jobs")
.child(_firebaseAuth.currentUser.uid)
.once()
.orderByKey().then((result) async {
if (result.value != null) {
result.value.forEach((key, childSnapshot) {
userJobs.add(Job.fromJson(key, Map.from(childSnapshot)));
});
} else {
print(
'getUserJobs() no jobs found');
}
}).catchError((e) {
print(
'getUserJobs() error: $e');
});
// if (query == null) {
// return userJobs;
// }
// query.onValue.listen((event) {
// Map<dynamic, dynamic> values = event.snapshot.value;
// values.forEach((key, value) {
// userJobs.add(Job.fromJson(key, Map.from(value)));
// });
// });
return userJobs;
}
ваш цикл также должен быть асинхронным .. в противном случае метод вернется до завершения цикла, возвращая пустой список.. был там и был очень разочарован этим..
также всегда используйте .catchError
обратный вызов .. он сообщает вам, что происходит не так 😉
Комментарии:
1. Это действительно работает! Единственное, что нужно было изменить, это то, что .orderByKey() должен быть before .once() в противном случае вы получите сообщение об ошибке. Приветствия!
2. Уверен
.once()
, что это тип запроса, поэтому он идет последним .. не заметил, что этого не было при редактировании вашего кода.. Рад, что смог помочь. Как я уже сказал, если вы выходите в Интернет, все становится немного сложнее, поскольку официальные пакеты для всех служб firebase еще недоступны.. дайте мне знать, если вам тоже понадобится помощь в этом.. Приветствия