issue with initializing List in a Future builder flutter firebase: LateInitializationError: Field 'posts' has not been initialized

Issue

I am having trouble with this future builder and can not seem to find the solution. I’m trying to create a List of documents("posts) mapped to a custom class I created("BlogPosts") but when attempting to use it I get the following error.

error:

LateInitializationError: Field 'posts' has not been initialized.

the stack trace tells me the error is happening inside the builder but I have already initialized ‘posts’ in the future

future builder:

late User user;
late Userdata userdata;
CollectionReference usersRef = FirebaseFirestore.instance.collection('users');
CollectionReference postsRef = FirebaseFirestore.instance.collection('posts');
late List<BlogPost> posts;

FutureBuilder(
          future: Future.wait([
            usersRef.doc(user.uid).get().then((doc) {
            userdata = Userdata.fromDocument(doc);
            }),
            postsRef.get().then((val) {
              posts = val.docs.map((doc) => BlogPost.fromDocument(doc)).toList();
            })
    ]),
          builder: (context, snap) {
            print(posts);
            if(snap.connectionState == ConnectionState.done) {
              return ListView.builder(
                physics: BouncingScrollPhysics(),
                  itemCount: 3,
                  itemBuilder: (context, index) {
                  return Text(userdata.displayName);
                  }
              );
            } else {
              return Center(
                child: Text('Loading')
              );
            }
          }
        )

full code:

late User user;
late Userdata userdata;
CollectionReference usersRef = FirebaseFirestore.instance.collection('users');
CollectionReference postsRef = FirebaseFirestore.instance.collection('posts');

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

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final auth = FirebaseAuth.instance;
  late List<BlogPost> posts;

  @override
  Widget build(BuildContext context) {
    user = auth.currentUser!;
    Color getColor(Set<MaterialState> states) {
      const Set<MaterialState> interactiveStates = <MaterialState>{
        MaterialState.pressed,
        MaterialState.hovered,
        MaterialState.focused,
      };
      if (states.any(interactiveStates.contains)) {
        return Colors.blue.shade900;
      }
      return Colors.blue.shade600;
    }
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.blue,
        child: Icon(
          Icons.add,
          color: Colors.white,
        ),
        onPressed: (){
          Navigator.push(context, MaterialPageRoute(builder: (_) => Upload()));
        },
      ),
        appBar: AppBar(
          backgroundColor: Colors.grey[600],
          actions: [
            TextButton(
              child: Text(
                'Logout',
                style: TextStyle(color: Colors.black),
              ),
              onPressed: () {
                auth.signOut();
                Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => LoginScreen()));
              },
              style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.resolveWith(getColor)
              ),
            ),
          ],
        ),
        // body: Center(
        //   child: Text(user.uid)
        // ),

        body: FutureBuilder(
          future: Future.wait([
            usersRef.doc(user.uid).get().then((doc) {
            userdata = Userdata.fromDocument(doc);
            }),
            postsRef.get().then((val) {
              posts = val.docs.map((doc) => BlogPost.fromDocument(doc)).toList();
            })
    ]),
          builder: (context, snap) {
            print(posts);
            if(snap.connectionState == ConnectionState.done) {
              return ListView.builder(
                physics: BouncingScrollPhysics(),
                  itemCount: 3,
                  itemBuilder: (context, index) {
                  return Text(userdata.displayName);
                  }
              );
            } else {
              return Center(
                child: Text('Loading')
              );
            }
          }
        )
    );
  }
}

class Userdata {

  final String uid;
  final String email;
  final String displayName;


  Userdata(this.uid, this.email,  this.displayName);

  factory Userdata.fromDocument(DocumentSnapshot doc) {
    return Userdata(
        doc['uid'],
        doc['email'],
        doc['displayName']
    );
  }
}

class BlogPost {
  String displayName;
  String postmsg;
  String postId;
  String UserId;

  BlogPost(this.displayName, this.postmsg, this.postId, this.UserId);

  factory BlogPost.fromDocument(DocumentSnapshot doc) {
    return BlogPost(
        doc['displayName'],
        doc['postmsg'],
        doc['postId'],
        doc['UserId']
    );
  }

Solution

I figured out my problem, as out my code was fine the entire time I just had a typo in my fromDocument my userId string was doc['UserId'] and was uploaded as 'userId' just one misplaced Uppercase.

Thanks so much for the help

Answered By – RyanBuss01

Answer Checked By – Willingham (FlutterFixes Volunteer)

Leave a Reply

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