Flutter-Firebase rtdb, fetching child values return as empty

Issue

I am trying to retrieve a child’s value from firebase RTDB and putting them into a list, but the values return empty, upon printing the list, it is empty too. The code used to work without any issues, the only changes I made was updating Flutter and dependencies to the latest versions.

Code:

lastPosition() async {
    print(searchID);
    // This method grabs the stream of location that is being sent to the database
    print("\n\n\nFetching Coordinates\n\n");
    databaseReference
        .child("users")
        .child("Driver Coordinates")
        .child(searchID)
        .once()
        .then(
      (DataSnapshot lastPosSnapshot) {
        setState(
          () {
            lastLatLng.add(
              lastPosSnapshot.value["latitude"],
            );
            lastLatLng.add(
              lastPosSnapshot.value["longitude"],
            );
            Future.delayed(
              Duration(milliseconds: 100),
            );
          },
        );
      },
    );
    print(lastLatLng);
    await getAdressBasedLocation();
  }

Solution

Data is loaded from Firebase asynchronously, and while that is happening your main code continues to execute. In practice this means that your print(lastLatLng); runs before any of the lastLatLng.add(...) calls after ever executed, something you can most easily check by adding some logging inside the then() handler too.

In practice this means that any code that needs the data from the database has to be inside the then callback, or you have to use await to block the once call (in which case you also have to mark lastPosition as async and use await or then on any calls to it.

So moving the call to inside the then callback:

databaseReference
    .child("users")
    .child("Driver Coordinates")
    .child(searchID)
    .once()
    .then((DataSnapshot lastPosSnapshot) {
    lastLatLng.add(lastPosSnapshot.value["latitude"]);
    lastLatLng.add(lastPosSnapshot.value["longitude"]);

    print(lastLatLng); // 👈
    ...
  },
);

Or by using await:

var lastPosSnapshot = await databaseReference
    .child("users")
    .child("Driver Coordinates")
    .child(searchID)
    .once();
lastLatLng.add(lastPosSnapshot.value["latitude"]);
lastLatLng.add(lastPosSnapshot.value["longitude"]);

print(lastLatLng); // 👈

Answered By – Frank van Puffelen

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.