How to access parameters from Stream

Viewed 82

I'm getting values from my database and storing into a Map, and after in a List. Because I will need the content from the List to create buttons in my main page. I have created a Stream with returns me the right content from the Firebase:

Stream<List> readData() async*{
    Map<dynamic, dynamic> button_list = Map();
    var lst = [];

    final FirebaseUser user = await _auth.currentUser();

    Stream stream = await databaseReference.child(user.uid+"/buttons/").onValue.forEach((element) {
      button_list = element.snapshot.value as Map;
      lst = button_list.values.toList();
      print(lst);
    });

    await for(var event in stream) {
      yield event.lst;
    }
  }

This is the content from the button_list:

{botao: {icon: delte, nome: Junior}, button1: {icon: add, nome: Televisao}, button2: {icon: bulb, nome: BAtata}}

This is the content from the list after I assigned the button_list to lst:

[{icon: delte, nome: Junior}, {icon: add, nome: Televisao}, {icon: bulb, nome: BAtata}]

When I attempt to access the content from my List in the main screen I get the result as 0:

 body: StreamBuilder(
        stream: _auth.readData(),
        initialData: 0,
        builder: (context, snapshot) {
          if (snapshot.hasError || snapshot.hasError){
            return Container(color: Colors.red);
          }
          if (!snapshot.hasData || !snapshot.hasData){
            return Center(child: CircularProgressIndicator());
          }
          if (snapshot.hasData || snapshot.hasData){
            return GridView.count(
              padding: EdgeInsets.all(15),
              crossAxisSpacing: 20.0,
              mainAxisSpacing: 20.0,
              crossAxisCount: 3,
              children: [
                CreateCard("ola"),
                GestureDetector(
                  onTap: () async{
                    print(snapshot.data[0]);
                  },
                    child: Container(
                    color: Colors.black,
                    width: 150,
                    height: 150,
                    child: Icon(Icons.add, color: Colors.white,),
                    
                  ),
                ),
              ],
            );
          }
        }
      ),

I'm using the GestureDetector to read the content from the positions.

1 Answers

Invoking the forEach method returns a Future not a Stream ([reference])(https://api.dart.dev/stable/2.10.5/dart-async/Stream/forEach.html)

So maybe something along these lines (haven't tested it):

Stream<List> readData() async*{
  Map<dynamic, dynamic> button_list = Map();
  var lst = [];

  final FirebaseUser user = await _auth.currentUser();

  // Note the removed `await` keyword
  final lstValues = databaseReference.child(user.uid+"/buttons/").onValue.forEach((element) {
    button_list = element.snapshot.value as Map;
    lst = button_list.values.toList();
    print(lst);
  });
  final lstStream = Stream.fromFuture(lstValues);

  await for(var event in stream) {
    yield lst;
  }
}
Related