'A nullable expression can't be used as an iterator in a for-in loop. Try checking that the value isn't 'null' before using it as an iterator

I have to get data from Firebase Database and through the key "keys" take all the data and insert them in "postsList". To do this I used the for-in loop. The latter throws me an error.

The error is: "A nullable expression can't be used as an iterator in a for-in loop. Try checking that the value isn't 'null' before using it as an iterator."

class _HomePageState extends State<HomePage> {

  List<Posts> postsList = [];


  @override
  void initState() {

    super.initState();


    DatabaseReference postsRef = FirebaseDatabase.instance.reference().child("Posts");

    postsRef.once().then((snap)
        {

      var keys = snap.snapshot.key;
      var values = snap.snapshot.value;

      postsList.clear();

      for (var individual in keys) {
        Posts posts = Posts(
          values[individual]['url'],
          values[individual]['descrizione'],
          values[individual]['data'],
          values[individual]['ora'],
        );
        postsList.add(posts);
      }


      setState(()
      {
       print('Length : $postsList.length');
      });

    });
  }


Solution 1:[1]

The error message should come with a link to this documentation page on unchecked use of a nullable value. As the error says, the keys variable you use in for (var individual in keys) { can be null, which isn't allowed. You should either check if it's null, or assert that it isn't null:

if (keys != null) {
  for (var individual in keys) {
    Posts posts = Posts(
      values[individual]['url'],
      values[individual]['descrizione'],
      values[individual]['data'],
      values[individual]['ora'],
    );
    postsList.add(posts);
  }
}

The above fixes the syntax/compiler problem, but there may well be other problems in your code as I suspect that your keys variable will be a single string with the value Posts. If that's the case, consider looping over values instead, with the same null check as above.


Map<String,int>.from(event.snapshot.value)

map.forEach((k, v) => print("Key : $k, Value : $v"));

DatabaseReference postsRef = FirebaseDatabase.instance.reference().child("Posts");

postsRef.once().then((snap) {
  // ? Get a map of the top-level post keys and post values
  var map = Map<String, dynamic>.from(snap.snapshot.value);

  postsList.clear();

  // ? Loop over the post keys and post values
  map.forEach((key, value) {
    // ? Get the values for this post as another map
    var values = Map<String, dynamic>.from(map);
    Posts posts = Posts(
      values['url'],
      values['descrizione'],
      values['data'],
      values['ora'],
    );
    postsList.add(posts);
  });

  setState(() {
    print('Length : $postsList.length');
  });
});

Solution 2:[2]

Add ! behind keys, for example : for(key in keys!

  @override
  void initState() {

    super.initState();


    DatabaseReference postsRef = FirebaseDatabase.instance.reference().child("Posts");

    postsRef.once().then((snap)
        {

      var keys = snap.snapshot.key;
      var values = snap.snapshot.value;

      postsList.clear();

      for (var individual in keys!) {
        Posts posts = Posts(
          values[individual]['url'],
          values[individual]['descrizione'],
          values[individual]['data'],
          values[individual]['ora'],
        );
        postsList.add(posts);
      }


      setState(()
      {
       print('Length : $postsList.length');
      });

    });
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 AlexisG