Warm tip: This article is reproduced from serverfault.com, please click

flutter firestore stream mapping to another stream

发布于 2020-11-28 03:21:07

I have a menus collection on firestore and I want to perform a map operation on each document and return a new stream. So, instead of the Stream<QuerySnapShop>, I wanted Stream<VendorMenuItem>

  Stream<VendorMenuItem> getAllVendorMenuItems(String vendorId) async* {
    var collectionReference = fs.collection('restaurants').doc('$vendorId').collection("menus").snapshots();
    collectionReference.map((event) {
      print("mapping");

      event.docs.forEach((element) {
        return VendorMenuItem.fromMap(element.data());
      });
    });
  }

and I am calling it within a build method just to test my approach, and I got nothing printed on the console, here is how I called it

@override
  Widget build(BuildContext context) {
    var fs = Provider.of<FireStoreDatabaseRoute>(context);

    fs.getAllVendorMenuItems("ewP3B6XWNyqjM98GYYaq").listen((event) {
      print("printing  final result");
      print(event.name);
    });

Any clues? thank you

UPDATE:

I wasn't yielding anything, however the yield keyword didnt help

  Stream<VendorMenuItem> getAllVendorMenuItems(String vendorId) async* {
    var collectionReference = FirebaseFirestore.instance.collection('restaurants').doc('$vendorId').collection("menus").snapshots();
    yield* collectionReference.map((event) => event.docs.map((e) => VendorMenuItem.fromMap(e.data())));
  }
Questioner
Brendon Cheung
Viewed
0
Taha Malik 2020-11-28 18:55:28

This is how you transform stream using the method you use.

Stream<List<VendorMenuItem>> getAllVendorMenuItems(String vendorId) async* {
    var collectionReference =
        FirebaseFirestore.instance.collection('Files').snapshots();
    yield* collectionReference.map(
      (event) => event.docs
          .map(
            (e) => VendorMenuItem.fromMap(e.data()),
          )
          .toList(), //Added to list to Match the type, other wise dart will throw an error something Like MappedList is not a sub type of List
    );
  }

    

This is a second way to achieve the same task using a stream controller.

  Stream<List<VendorMenuItem>> getAllVendorMenuItems2(String vendorId) {
    StreamController<List<VendorMenuItem>> controller =
        StreamController<List<VendorMenuItem>>();
    FirebaseFirestore.instance.collection("Files").snapshots().listen((event) {
      controller.add(event.docs
              .map(
                (e) => VendorMenuItem.fromMap(e.data()),
              )
              .toList() //ToList To Match type with List
          );
    });

    return controller.stream;
  }