2

I have this method:

Future<AppUser> _getUser(String documentId) async {
    var document = await firestore.collection('customers').doc(documentId);
    document.get().then((DocumentSnapshot documentSnapshot) {
          print(documentSnapshot.data());
    });
    AppUser bruceUser = AppUser(userId: 'user006',);

    return bruceUser;   
}

And below it, I have a variable that uses this method:

AppUser _user = await _getUser(document.id);

However, this returns the following error:

Error: 'await' can only be used in 'async' or 'async*' methods.

What am I doing wrong here? I don't want to change _user to Future, because it will complicate the code further, so why doesn't the await work?

IB MR
  • 365
  • 1
  • 4
  • 16
  • What about the function you are calling `AppUser _user = await _getUser(document.id);`? Is it async? – JustCode Nov 19 '20 at 17:43
  • @JustCode, no. it's a `snapshot.data.docs.map((DocumentSnapshot document){` function. I tried making it async, but it returns `Error: The argument type 'List>' can't be assigned to the parameter type 'List'` – IB MR Nov 19 '20 at 17:45
  • Then it is the problem, why don't you try `_getUser(document.id).then((user){//code here})` – JustCode Nov 19 '20 at 17:49
  • @JustCode do i put the snapshot in `then`? – IB MR Nov 19 '20 at 17:50
  • Please check the answer. I think it will clear your problem. – JustCode Nov 19 '20 at 17:58
  • 1
    Does this answer your question? [What is a Future and how do I use it?](https://stackoverflow.com/questions/63017280/what-is-a-future-and-how-do-i-use-it) – nvoigt Nov 19 '20 at 18:58

1 Answers1

1

_getUser() is an asnyc function but not the calling function. The error you are getting states that, await was used in a non-async function. If you have difficulty in converting the caller function to async, try using then as follows.

snapshot.data.docs.map((DocumentSnapshot document) {
    _getUser(document.id).then((user) {
          //code here
    });
}

In summary, there are two solutions for this

  1. Convert the caller function to async.
  2. Use _getUser().then((user){});
JustCode
  • 463
  • 2
  • 11
  • because of the await in _getUser(), it takes too long to run and I get ```"Column's children must not contain any null values, but a null value was found at index 0"```. I put a print statement in getUser() inside `document.get()` and one before `_getUser(document.id).then((user) {` and inside of it. The one before prints, then I get an error and then the one inside prints and lastly the on inside _getUser() prints. – IB MR Nov 19 '20 at 18:06
  • Are you using the data from this callback to build a `Column` widget? In such a case you have to either use a future builder or hold the column build process until you receive the data from the async callback. – JustCode Nov 19 '20 at 18:09
  • How can I hold the column build process? – IB MR Nov 19 '20 at 18:12
  • With help of a `StatefulWidget` and a single boolean value, you can archive the same. Based on the boolean value you can display a column data or a loading widget. – JustCode Nov 19 '20 at 18:19
  • I'm trying, but again didn't work. Because ```snapshot.data.docs.map((DocumentSnapshot document) {``` is inside column, it doesn't get called. – IB MR Nov 19 '20 at 18:33
  • Does this https://stackoverflow.com/questions/58978730/how-to-use-async-code-inside-map-flutter-firestore helps? – JustCode Nov 19 '20 at 18:35