如何从DataSnapshot返回未来列表

时间:2019-09-02 20:23:07

标签: flutter dart

我想从Firebase数据库快照返回一个“将来列表”,这是我的代码,但是我无法使其正常工作:

Future<List<CocheDetailItem>> getCoches(ids) async {
  List<CocheDetailItem> coches = [];
  final dbRef = FirebaseDatabase.instance.reference().child('17082019');
  for (var i = 0; i < ids.length; i++) {
    var id = ids[i];
    dbRef.child(id).once().then((DataSnapshot snapshot) {
      if (snapshot.value != null) {
        Map<dynamic, dynamic> jsres = snapshot.value;
        CocheDetailItem coche = CocheDetailItem.fromJson(jsres);
        coches.add(coche);
      }
    });
    print('here is i ${ids[i]} ');
  }
  return coches;

}

我得到的回报是空白区域。有人可以帮我吗?

2 个答案:

答案 0 :(得分:1)

请注意,dbRef.child(id).once();是一个异步函数,因此必须等待它结束才能获取数据。使用await关键字。

Future<List<CocheDetailItem>> getCoches(ids) async {
      List<CocheDetailItem> coches = [];
      final dbRef = FirebaseDatabase.instance.reference().child('17082019');
      for (var i = 0; i < ids.length; i++) {
        var id = ids[i];
        var dataSnapshot = await dbRef.child(id).once();
          if (dataSnapshot.value != null) {
            Map<dynamic, dynamic> jsres = dataSnapshot.value;
            CocheDetailItem coche = CocheDetailItem.fromJson(jsres);
            coches.add(coche);
          }
        print('here is i ${ids[i]} ');
      }
      return coches;
    }

答案 1 :(得分:1)

好吧..我不使用firebase,但是我使用它发送请求到我的数据库(必须使用异步并等待)

  Future<List<PlaceModel>> getPlaces(String ciudad, String tipo) async {
    Uri request = Uri.http('domain.com', '/getPlaces/$ciudad/$tipo');
    ResponseModel response = ResponseModel.fromJsonMap(json.decode((await http.get(request)).body));
    List<PlaceModel> items = [];
    if(response.res) {
      if(response.value != null) {
        for(var item in response.value) {
          final place = PlaceModel.fromJsonMap(item);
          items.add(place);
        }
      }
    }
    print("Places Loaded: ${items.length}");
    return items;
  }

我使用ResponseModel在对象中转换json答案。 然后,我向未来的建造者展示它:

class PlacesListPage extends StatelessWidget{
  final _selectedLocation, _selectedList;
  PlacesListPage(this._selectedLocation, this._selectedList);

  final _provider = PlaceProvider();

  @override
  Widget build(BuildContext context) {
    return Container(
          padding: EdgeInsets.all(8.0),
          child: FutureBuilder(
            future: _provider.getPlaces(_selectedLocation, _selectedList), // async request to database
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.hasData) { // check when your request is done
                if(snapshot.data.length != 0) { // check if any data has been downloaded
                  return ListView.builder( // build a listview of any widget with snapshot data
                    itemCount: snapshot.data.length,
                    itemBuilder: (BuildContext context, int index) {
                      // i just return containers but you can use any custom widget, it's like a forEach and use the index var
                      return Container( 
                        child: Text(snapshot.data[index]),
                      );
                    },
                  );
                } else {
                  // If you don't have anything in your response shows a message
                  return Text('No data');
                }
              } else {
                // shows a charge indicator while the request is made
                return Center(
                  child: CircularProgressIndicator(),
                );
              }
            },
          ),
        );
  }
}