Home > Enterprise >  Collecting string from Firebase Firestore in flutter
Collecting string from Firebase Firestore in flutter

Time:10-08

I am creating like system and i want to get likeCount from firebase which i created.

data which i want to collect

It's collecting it but returns null, here is my code:

  String? getLikecount(tresc) {
String? likeCount;
FirebaseFirestore.instance
    .collection('Posty')
    .where('Tresc', isEqualTo: tresc)
    .get()
    .then((value) => value.docs.forEach((element) async {
          var id = element.id;
         final value = await FirebaseFirestore.instance.collection('Posty').doc(id).get();
          
            likeCount = value.data()!['likeCount'].toString();
            print(likeCount);
        }));
print(likeCount);
return likeCount;
}

and here is console output:

console output

CodePudding user response:

Data is loaded from Firestore (and most modern cloud APIs) asynchronously, because it may needs to come from the network and we can't block your code (and your users) while waiting for it.

If we change the print statements a bit, and format the code, it'll be much easier to see what's going on:

String? getLikecount(tresc) {
  String? likeCount;
  FirebaseFirestore.instance
      .collection('Posty')
      .where('Tresc', isEqualTo: tresc)
      .get()
      .then((value) => value.docs.forEach((element) async {
            var id = element.id;
            final value = await FirebaseFirestore.instance
                .collection('Posty')
                .doc(id)
                .get();

            likeCount = value.data()!['likeCount'].toString();
            print('In then: $likeCount');
          }));
  print('After then: $likeCount');
  return likeCount;
}

If you run this, you'll see it outputs:

After then: null

In then: 0

This is probably not what you expected, but it explains perfectly why you don't get a result. By the time your return likeCount runs, the likeCount = value.data()!['likeCount'].toString() hasn't executed yet.

The solution is always the same: any code that needs the data from the database has to be inside the then handler, be called from there, or be otherwise synchronized.

In Flutter it is most common to use async and await for this. The key thing to realize is that you can't return something now that hasn't been loaded yet. With async/await you function becomes:

Future<String?> getLikecount(tresc) {
  String? likeCount;
  var value = await FirebaseFirestore.instance
      .collection('Posty')
      .where('Tresc', isEqualTo: tresc)
      .get();

  for (var doc in value.docs) {
    var id = element.id;
    final value = await FirebaseFirestore.instance
        .collection('Posty')
        .doc(id)
        .get();

    likeCount = value.data()!['likeCount'].toString();
    print('In then: $likeCount');
  }));

  print('After then: $likeCount');
  return likeCount;
}

Now your code returns a Future<String?> so a value that at some point will hold the string. When calling getLikecount you will now need to use then or await to handle the Future, and if you want to show the count in the UI you will have to store it in the State of a StatefulWidget.

  • Related