me0076
me0076

Reputation: 23

Stream and Future in flutter

I am using Firebase as backend. Each user has some items and these items cannot be seen by other users. User items are stored in a sub-collection. This is how the structure looks like: User collection -> User id as document id -> in each document, a sub-collection of items -> item as document.

The app needs to get user id from Firestore and then it can show items of the user.

@override
Stream<List<Item>> items() {
 final currentUserId = userRepo.getUserUid();
 return Firestore.instance.collection('users')
 .document(currentUserId) //error here
 .collection("items").snapshots().map((snapshot) {
  return snapshot.documents
  .map((doc) => Item.fromEntity(ItemEntity.fromSnapshot(doc)))
  .toList();
   });
      }
Future<String> getUserUid() async {
 return (await _firebaseAuth.currentUser()).uid;
 }

currentUser throws the following error:

The argument type 'Future<String>' can't be assigned to the parameter type 'String'. 

I understand that the parameter expects a String and I can't assign a Future but I don't know how use future with stream and resolve the issue. If I replace currentUserId variable with a String like "36o1avWh8cLAn" (the actual user id) it does work.

Any help would be appreciated.

Update: thanks to Viren V Varasadiya the problem is solved.

@override
Stream<List<Item>> items() async*{
 final currentUserId = userRepo.getUserUid();
 yield* Firestore.instance.collection('users')
 .document(currentUserId) //error here
 .collection("items").snapshots().map((snapshot) {
  return snapshot.documents
  .map((doc) => Item.fromEntity(ItemEntity.fromSnapshot(doc)))
  .toList();
});
  }

Upvotes: 0

Views: 319

Answers (1)

Viren V Varasadiya
Viren V Varasadiya

Reputation: 27137

You can use async* annotation to use await in function which return stream.

Stream<List<Item>> items() async*{
  final currentUserId = await userRepo.getUserUid();
  yield Firestore.instance.collection('users')
    .document(currentUserId) //error here
    .collection("items").snapshots().map((snapshot) {
      return snapshot.documents
        .map((doc) => Item.fromEntity(ItemEntity.fromSnapshot(doc)))
        .toList();
    });
}

Upvotes: 1

Related Questions