0

I am working on a project where I have employees scan items into a bin. I am trying to load the information from the database. I have looked at many different posts and found things similar, but never anything that worked.

I have a list (binListDBList) that I am adding data into, then I want to do stuff with it after. I do get a response and it is the correct data, but I have to do a timed delay instead of await. It is clunky and am wondering what a better solution would be.

I have tried async/await and .then and nothing has worked so far. I know there is a solution, but I have spent a lot of time and haven't gotten anywhere.

I have added in a bunch of print statements for testing.

Starting method:

Future<void> loadBinListFromDB(String empID, String binName) async {
  print("start");
  DatabaseService.binListDBList.clear();
  print("Zero: " + DatabaseService.binListDBList.toString());


  await DatabaseService().getBinList(empID, binName);

  print("test");

  if (DatabaseService.binListDBList.isEmpty) {
    print("No Data");
  } else {
    print("data");
  }
  print("Fifth: " + DatabaseService.binListDBList.toString());

  Future.delayed(new Duration(seconds: 1)).then((value) {
    print("last: " + DatabaseService.binListDBList.toString());
  });

  print(DatabaseService.binListDBList);
  return;
}

DatabaseService class

static List<BinListDB> binListDBList = [];

Future<void> getBinList(String employeeID, String binName) async {
    print(employeeID);

    List<BinListDB> hold = [];
    print("First: $binListDBList");
    binListCollection
        .doc(employeeID)
        .collection(binName)
        .snapshots()
        .forEach((element) {
      for (int i = 0; i < element.docs.length; i++) {
        hold.add(BinListDB.fromFireStore(element.docs[i]));
      }
      print("Second: $binListDBList");
      binListDBList = hold;
      print("Third: $binListDBList");
    });
    print("Fourth: $binListDBList");
    return;

  }

output:

I/flutter (26448): start
I/flutter (26448): Zero: []
I/flutter (26448): EmployeeID
I/flutter (26448): First: []
I/flutter (26448): Fourth: []
I/flutter (26448): test
I/flutter (26448): No Data
I/flutter (26448): Fifth: []
I/flutter (26448): finish
I/flutter (26448): Second: []
I/flutter (26448): Third: [Instance of 'BinListDB']
I/flutter (26448): last: [Instance of 'BinListDB']

I don't understand why it isn't printing in order.

1
  • Are you sure that the problem is not in delays at the terminal itself? I had a similar problem in other languages several times and it was just the problem with "typing" in the terminal. Maybe you can put the data into a array and print it at the end? Commented May 19, 2022 at 21:11

1 Answer 1

1

You currently are doing:

    binListCollection
        .doc(employeeID)
        .collection(binName)
        .snapshots()
        .forEach((element) {
      ...
    });

snapshots() returns a Stream, which is asynchronous. You call Stream.forEach to iterate over each element of the Stream, and Stream.forEach returns a Future to indicate when it's complete, but you neglect to await that Future. The caller of Stream.forEach therefore continues executing immediately, and you see "Fourth" printed (and later "Fifth" and "finished") before Stream.forEach's callback prints "Second" and "Third".

That is, you need to change it to:

    await binListCollection
        .doc(employeeID)
        .collection(binName)
        .snapshots()
        .forEach((element) {
      ...
    });

I strongly suggest enabling the unawaited_futures lint to let the analyzer catch such errors.

Sign up to request clarification or add additional context in comments.

2 Comments

What is the difference from what I am doing? I should mention that in FireStore the data is structured as such: (Collection > Document > Collection > Document > Fields) BinList > EmployeeID > binName > itemID > Fields
@mjdk99 As I stated, you need to await your call of Stream.forEach. I've updated my answer for clarity.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.