Nested StreamBuilder doesn't work with inner parent's outputs

Viewed 37

I have two StreamBuilders and want to use one StreamBuilder's outputs for another StreamBuilder. For that, I made a nested StreamBuilder but it doesn't work. The child StreamBuilder seems not to take the parent StreamBulder's output well. In my code, userModelSnapshot always has no data. I checked functions inside both stream sources work.

I got some error code " _CastError (type 'Null' is not a subtype of type 'Map<dynamic, dynamic>' in type cast)" and "UserService.getUserInfo anonymous closure"

Any help would be appreciated.

Here is my code

class ListPostsPage extends StatefulWidget {
  const ListPostsPage({Key? key}) : super(key: key);

  @override
  State<ListPostsPage> createState() => _ListPostsPageState();
}

class _ListPostsPageState extends State<ListPostsPage> {
  PostService postService = PostService();
  UserService userService = UserService();

  @override
  Widget build(BuildContext context) {
    String location = context.read<LocationModel?>()?.city! ?? '';

    return StreamBuilder(
        stream: postService.getPosts(location),
        builder:
            (BuildContext context, AsyncSnapshot<List<PostModel?>?> snapshot) {
          if (!snapshot.hasData) {
            return const Center(child: CircularProgressIndicator());
          }
          return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (context, index) {
                final post = snapshot.data![index];
                
                return StreamBuilder(
                    stream: userService.getUserInfo(post?.creator ?? ''),
                    builder: (BuildContext context,
                        AsyncSnapshot<UserModel?> userModelSnapshot) {
                          
                      if (!userModelSnapshot.hasData) {
                        return const Center(child: CircularProgressIndicator());
                      }
                      inspect(userModelSnapshot);

                      return Card(
                        color: Colors.grey[300],
                        child: ListTile
                          title: Padding(
                            padding: EdgeInsets.fromLTRB(0, 15, 0, 15),
                            child: Row(
                              children: [
                                Text(
                                    userModelSnapshot.data?.toString() ?? 'NO'),
                                userModelSnapshot.data?.profileImageUrl != null
                                    ? CircleAvatar(
                                        radius: 20,
                                        backgroundImage: NetworkImage(
                                            userModelSnapshot
                                                .data!.profileImageUrl!))
                                    : const Icon(
                                        Icons.person,
                                        size: 40,
                                      ),
                                SizedBox(width: 10),
                                userModelSnapshot.data?.name != null
                                    ? Text(userModelSnapshot.data!.name!)
                                    : const Text('No name')
                              ],
                            ),
                          ),
                          subtitle: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Padding(
                                padding: EdgeInsets.fromLTRB(0, 15, 0, 15),
                                child: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      Text(
                                        post?.text ?? "",
                                        style: TextStyle(color: Colors.black),
                                      ),
                                      SizedBox(height: 20),
                                      //Text(post.creator),
                                      Text((post?.timestamp.toDate() ?? 0)
                                          .toString()),
                                    ]),
                              ),
                            ],
                          ),
                        ),
                      );
                    });
              });
        });
  }
}
  Stream<List<PostModel>?> getPosts(location) {
    return FirebaseFirestore.instance
        .collection("posts")
        .where("location.city", isEqualTo: location)
        .snapshots()
        .map((snapshot) {
      return snapshot.docs.map((doc) {
        return PostModel(
          id: doc.id,
          creator: (doc.data())["creator"] ?? "",
          text: (doc.data())["text"] ?? "",
          timestamp: (doc.data())["timestamp"] ?? 0,
          location: (doc.data())["location"] ?? {},
        );
      }).toList();
    }
 
Stream<UserModel?> getUserInfo(uid) {
    return FirebaseFirestore.instance
        .collection('users')
        .doc(uid)
        .snapshots()
        .map((snapshot) {
      return UserModel(
          id: snapshot.id,
          name: (snapshot.data() as Map)['name'] ?? '',
          email: (snapshot.data() as Map)['email'] ?? '',
          profileImageUrl: (snapshot.data() as Map)['profileImageUrl'] ?? '',
          timestamp: (snapshot.data() as Map)['timestamp'] ?? 0);
    });
  }

0 Answers
Related