Трепетание Возвращаемый тип ‘Map’ не является ‘void’, как того требует контекст закрытия

#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 для примера потока.

3. я думаю, что для меня это слишком сложно. я получаю «Экземпляр ‘_MapStream<Событие, Карта<динамический, динамический>>» я думал, что получу обратно Map<Строка, Int>, и я могу использовать эту карту напрямую для создания виджетов в цикле for . возможно, мне нужен для работы с моделями, чтобы я мог получать данные в модель, а затем создавать виджеты из модели.