0

For some reason, my data variable keeps returning null outside of my .get() call. Within the .get() call, when I print data, I get the expected map. Any insight is appreciated! The part of the code that is giving me issues are in asterisks.

class _MessagesScreenState extends State<MessagesScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
          children: <Widget>[
            Expanded(
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.white,
                ),
                child: StreamBuilder(
                    stream: rtdb
                        .child('messages')
                        .child(widget.currentUserID)
                        .onValue,
                    builder: (context, snapshot) {
                      final messageList = <BuildMessages>[];
                      if (snapshot.hasData) {
                        final users = Map<String, dynamic>.from(
                            snapshot.data.snapshot.value);
                        users.forEach((key, value) {
                          **var data;**
                          **usersRef.child(key).get().then((value) {
                            data = new Map<String, dynamic>.from(value.value);
                          });**
                          final messageTile = BuildMessages(
                            name: data['userFirstName'] +
                                ' ' +
                                data['userLastName'],
                            picture: data['userImageUrl'],
                            otherID: data['userID'],
                          );
                          ;
                          messageList.add(messageTile);
                        });
                      }
                      return ListView.builder(
                        padding: EdgeInsets.only(top: 15.0),
                        itemCount: messageList.length,
                        itemBuilder: (context, index) {
                          return messageList[index];
                        },
                      );
                    }),
              ),
            ),
          ],
        ),
    );
  }

1 Answers1

1

That is the expected behavior. The usersRef.child(key).get() returns a Future<DataSnapshot?>, so you'll need to wrap it into a FutureBuilder to use its value.

Based on this answer that'd be something like:

FutureBuilder<DataSnapshot?>(
  future: usersRef.child(key).get(), // async work
  builder: (BuildContext context, AsyncSnapshot<DataSnapshot?> snapshot) {
    switch (snapshot.connectionState) {
      case ConnectionState.waiting: return Text('Loading....');
      default:
        if (snapshot.hasError)
          return Text('Error: ${snapshot.error}');
        else
          return Text('Result: ${snapshot.data!.value}');
    }
  },
)
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807