#flutter #dart
#трепетание #dart
Вопрос:
Привет, я хочу вернуть карту из FirebaseDatabase. Но я получаю код ошибки:
Возвращаемый тип ‘Map<int, int>’ не является ‘void’, как того требует контекст закрытия.
если я напечатаю карту, я получу правильный результат. Я новичок в Flutter и не понимаю, почему он не работает. Я думаю, мне нужно изменить тип метода, но как?
String u1= 'Backsquat';
Dataread(String u1);
DatabaseReference data = FirebaseDatabase.instance.reference();
FirebaseAuth auth = FirebaseAuth.instance;
Map? read() {
Map <int,int> werte;
data.child("Kraftwerte").child(auth.currentUser.uid).child(u1).onValue.listen((event) {
werte = event.snapshot.value;
print(werte);
return werte;
}); ```
Комментарии:
1. Я не работал с Firebase, но эта
listen
функция выглядит как потоковый интерфейс, который является асинхронным. Каждый раз, когда считывается значение, выполняется обратный вызов, который получает переданное значение. Ожидается, что этот обратный вызов вернетсяvoid
. Если вы хотите прочитать список значений, вам, вероятно, понадобитсяawait
другая функция.
Ответ №1:
Ошибка возникает из-за того, что ваш поток является асинхронным, в то время как ваша фактическая функция синхронна. Если все, что вы хотите, это вернуть event.snapshot.value
для каждого элемента в вашем потоке, вы можете сделать это:
Stream<Map?> read() {
return data.child("Kraftwerte").child(auth.currentUser.uid).child(u1).onValue.map<Map>((event) => event.snapshot.value);
}
Если вы хотите получить первое значение потока:
Future<Map?> read() async {
final event = await data.child("krafwerte").child(auth.currentUser.uid).child(u1).onValue.first;
return event.snapshot.value as Map?;
}
В любом случае, ваш код должен быть асинхронным
пример использования кода:
class MyWidget extends StatelessWidget {
@override
Widget buuld(BuildContext context) {
return FutureBuilder(
future: _read(),
builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error!);
if (snapshot.hasData) return Text(snapshot.data!['key']); // snapshot.data is the map, it's null if the future is not done.
return CircularProgressIndicator();
}
);
}
Future<Map> _read() {
final event = await data.child("krafwerte").child(auth.currentUser.uid).child(u1).onValue.first;
return event.snapshot.value as Map?;
}
}
Чтобы лучше понять, как работает виджет future builder, пожалуйста, ознакомьтесь с документами future builder
Комментарии:
1. Я думал, ЧТО ЭТО работает, потому что я напечатал resault и получил что-то обратно. Но у меня проблема в том, что я хочу включить resault в цикл For, чтобы создавать виджеты из карты. Но, похоже, я не получаю карту обратно в виде функции <Map<object, object>> или чего-то подобного. Есть ли просто получить карту из Stream / Future или привести ее к map и выполнить цикл Resault, чтобы получить из нее виджеты? Я прочитал документ flutter firebase, но они останавливаются в точке, когда они что-то делают с полученными данными. firebase.flutter.dev/docs/database/usage . Я понятия не имею, как это решить
2. Я добавил пример использования данных с помощью
FutureBuilder
виджета, вы также можете использовать виджет StreamBuilder для примера потока.