Migrating to null safety: The argument type 'Object?' can't be assigned to the parameter type 'List<Widget>'

Issue

After migrating to null safety I’m getting an error on ListView as "The argument type ‘Object?’ can’t be assigned to the parameter type ‘List’."
I’m getting error on return ListView(children: snapshot.data,);
Can anyone help me to fix this error and build a ListView for activityfeeditem in my app?

Here is my code for activity_feed.dart,

class ActivityFeed extends StatefulWidget {
@override
_ActivityFeedState createState() => _ActivityFeedState();
}

class _ActivityFeedState extends State<ActivityFeed> {

getActivityFeed() async {
 QuerySnapshot snapshot = await activityFeedRef
     .doc(currentUser!.id)
     .collection('feedItems')
     .orderBy('timestamp', descending: true)
     .limit(50)
     .get();
 List<ActivityFeedItem> feedItems = [];
 snapshot.docs.forEach((doc) {
   feedItems.add(ActivityFeedItem.fromDocument(doc));
   print('Activity Feed Item: ${doc.data}');
 });

 return feedItems;
}

@override
Widget build(BuildContext context) {
 return Scaffold(
   backgroundColor: Colors.deepPurple[50],
   appBar: header(context, titleText: "Activity Feed"),
   body: Container(
     child: FutureBuilder(
       future: getActivityFeed(),
       builder: (context, snapshot) {
         if (!snapshot.hasData) {
           return circularProgress();
         }
         return ListView(
           children: snapshot.data,

// Here I'm getting error on `snapshot.data`

         );
       },
     ),
   ),
 );
}
}

Widget? mediaPreview;
String? activityItemText;

class ActivityFeedItem extends StatelessWidget {
final String? username;
final String? userId;
final String? type; // 'like', 'follow', 'comment'
final String? mediaUrl;
final String? postId;
final String? userProfileImg;
final String? commentData;
final Timestamp? timestamp;

ActivityFeedItem({
 this.username,
 this.userId,
 this.type,
 this.mediaUrl,
 this.postId,
 this.userProfileImg,
 this.commentData,
 this.timestamp,
});

factory ActivityFeedItem.fromDocument(DocumentSnapshot doc) {
 return ActivityFeedItem(
   username: doc['username'],
   userId: doc['userId'],
   type: doc['type'],
   postId: doc['postId'],
   userProfileImg: doc['userProfileImg'],
   commentData: doc['commentData'],
   timestamp: doc['timestamp'],
   mediaUrl: doc['mediaUrl'],
 );
}

showPost(context) {
 Navigator.push(
     context,
     MaterialPageRoute(
         builder: (context) => PostScreen(postId: postId, userId: userId)));
}

configureMediaPreview(context) {
 if (type == "like" || type == 'comment') {
   mediaPreview = GestureDetector(
     onTap: () => showPost(context),
     child: Container(
       height: 50.0,
       width: 50.0,
       child: AspectRatio(
           aspectRatio: 16 / 9,
           child: Container(
             decoration: BoxDecoration(
               image: DecorationImage(
                 fit: BoxFit.cover,
                 image: CachedNetworkImageProvider(mediaUrl!),
               ),
             ),
           )),
     ),
   );
 } else {
   mediaPreview = Text('');
 }

 if (type == 'like') {
   activityItemText = "liked your post";
 } else if (type == 'follow') {
   activityItemText = "is following you";
 } else if (type == 'comment') {
   activityItemText = 'replied: $commentData';
 } else {
   activityItemText = "Error: Unknown type '$type'";
 }
}

@override
Widget build(BuildContext context) {
 configureMediaPreview(context);

 return Padding(
   padding: EdgeInsets.only(bottom: 2.0),
   child: Container(
     color: Colors.white54,
     child: ListTile(
       title: GestureDetector(
         onTap: () => showProfile(context, profileId: userId),
         child: RichText(
           overflow: TextOverflow.ellipsis,
           text: TextSpan(
               style: TextStyle(
                 fontSize: 14.0,
                 color: Colors.black,
               ),
               children: [
                 TextSpan(
                   text: username,
                   style: TextStyle(fontWeight: FontWeight.bold),
                 ),
                 TextSpan(
                   text: ' $activityItemText',
                 ),
               ]),
         ),
       ),
       leading: CircleAvatar(
         backgroundImage: CachedNetworkImageProvider(userProfileImg!),
       ),
       subtitle: Text(
         timeago.format(timestamp!.toDate()),
         overflow: TextOverflow.ellipsis,
       ),
       trailing: mediaPreview,
     ),
   ),
 );
}
}

showProfile(BuildContext context, {String? profileId}) {
Navigator.push(
 context,
 MaterialPageRoute(
   builder: (context) => Profile(
     profileId: profileId,
   ),
 ),
);
}

I have tried many ways but I counldn’t figure out how I can fix this

New code for list

Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.deepPurple[50],
        appBar: header(context, titleText: "Activity Feed"),
        body: Container(
          child: StreamBuilder<QuerySnapshot>(
              stream: activityFeedRef
                  .doc(currentUser!.id)
                  .collection('feedItems')
                  .orderBy('timestamp', descending: true)
                  .limit(50)
                  .snapshots(),
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return Center(
                    child: circularProgress(),
                  );
                } else
                  return ListView(
                    children: snapshot.data!.docs.map((doc) {
                      return Card(
                        child: ListTile(
                          title: GestureDetector(
                            onTap: () =>
                                showProfile(context, profileId: doc['userId']),
                            child: RichText(
                              overflow: TextOverflow.ellipsis,
                              text: TextSpan(
                                  style: TextStyle(
                                    fontSize: 14.0,
                                    color: Colors.black,
                                  ),
                                  children: [
                                    TextSpan(
                                      text: doc['username'],
                                      style: TextStyle(
                                          fontWeight: FontWeight.bold),
                                    ),
                                    TextSpan(
                                      text: ' $activityItemText',
                                    ),
                                  ]),
                            ),
                          ),
                          leading: CircleAvatar(
                            backgroundImage: CachedNetworkImageProvider(
                                doc['userProfileImg']!),
                          ),
                          subtitle: Text(
                            timeago.format(doc['timestamp']!.toDate()),
                            overflow: TextOverflow.ellipsis,
                          ),
                          trailing: mediaPreview,
                        ),
                      );
                    }).toList(),
                  );
              }),
        ));
  }

Solution

Chage your getActivityFeed

 Future<List<ActivityFeedItem>>   getActivityFeed() async {
 try{
   QuerySnapshot snapshot = await activityFeedRef
     .doc(currentUser!.id)
     .collection('feedItems')
     .orderBy('timestamp', descending: true)
     .limit(50)
     .get();
 List<ActivityFeedItem> feedItems = [];
 snapshot.docs.forEach((doc) {
   feedItems.add(ActivityFeedItem.fromDocument(doc));
   print('Activity Feed Item: ${doc.data}');
 });

 return feedItems;
}

catch (error) {
   print(error);
   return <ActivityFeedItem>[];
  }}

change you FutureBuilder as follows

FutureBuilder<List<ActivityFeedItem>>(
       future: getActivityFeed(),
       builder: (BuildContextcontext, AsyncSnapshot<List<ActivityFeedItem>> snapshot) {
         if (snapshot.hasError){
          return Center(child: Text("You have an error in loading 
          data"));   
          }
         if (snapshot.hasData) {
           return ListView(
           children: snapshot.data!,
         );
         }
         return CirclularProgressIndicator();

Answered By – Lakmal Fernando

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *