Home > Mobile >  Why the value of a variable does not change when using initState in flutter
Why the value of a variable does not change when using initState in flutter

Time:03-07

I have been trying to obtain the value of groupfav that is stored in FireStore to pass it as part of the reference to a Stream, but even when in initState I obtain the corresponding value, the original variable is not changed to the new value, therefore it does not load the list corresponding to the value obtained, I tried many solutions and ideas, but I can't make the String groupfav change to the new value.

static String? userID = FirebaseAuth.instance.currentUser?.uid;
  static final userColeccion =
      FirebaseFirestore.instance.collection("users");

  String groupfav = ' '; //this value should be replaced by the future value obtained
  late Stream<QuerySnapshot> task;

  @override
  void initState() {
    super.initState();

    userColeccion.doc("$userID").get().then((value) {
      groupfav = value.data()!["groupfav"];
      print(groupfav); //correctly prints the value I want (is "groupid4")
      return groupfav;
    });

    taskGroup = FirebaseFirestore.instance
        .collection("groups")
        .doc(groupfav) // pass the obtained value
        .collection("task")
        .snapshots();
  }

doing all this should replace String groupfav = ' '; to String groupfav = 'groupid4', but it doesn't work, it stays at ' ', thanks!

CodePudding user response:

You're doing a synchronous call by attaching a callback to the usersCollection.get() call. It is only inside the .then that the asynchronous call gets fulfilled. This call does not wait and it just continues right through to the next call, which is fetching the FirebaseFiresstore.instance, by then the value is still empty for the groupfav. What you need to do is nest that call inside the .then(), because it is then (pun intended!) when the value will be set because of how asynchronous calls work when using the .then chain of events, so do it like this:


userColeccion.doc("$userID").get().then((value) {
      groupfav = value.data()!["groupfav"];
      print(groupfav); //correctly prints the value I want (is "groupid4")
      
      // right inside the **.then, after getting the value
      // THEN you can fetch the document with name 'groupfav'
      // from your collection
      taskGroup = FirebaseFirestore.instance
        .collection("groups")
        .doc(groupfav) // pass the obtained value
        .collection("task")
        .snapshots();

});

Unfortunately you cannot make the initState asynchronous (decorating it with the async keyword), otherwise I would've suggested using the await instead of the .then. Another way would be to take all these oeprations into a separate method which indeed waits for the call on the usersCollection, as in:


@override
void initState() {
  super.initState();
  getGroupFavData();
}

void getGroupFavData() async {

  var groupFavData = await userColeccion.doc("$userID").get();
  var groupfav = groupFavData.data()!['groupfav'];

  taskGroup = FirebaseFirestore.instance
    .collection("groups")
    .doc(groupfav) // pass the obtained value
    .collection("task")
    .snapshots();

}
  • Related