flutterfirebasedartflutter-streambuilder

Placing a Firebase Stream in a method


When accessing data from Firebase a QuerySnapshot is commonly returned. Is there a way to wrap this method so instead of a QuerySnapshot the data can be cleaned so it will return, say, a List?

Currently, I'm accessing my collection like always:

StreamBuilder<QuerySnapshot?>(
  stream: FirebaseFirestore.instance
    .collection('users').snapshots(),
  builder: ...

I'm looking to wrap the stream in my own method so I can clean it up before returning the value.

StreamBuilder<List<int>>(
  stream: _cleanDataFromFirebase()          // now returning List<int>
  builder: ...

I initially tried

Stream<QuerySnapshot<Map<String, dynamic>>> _cleanDataFromFirebase() async* {
    yield FirebaseFirestore.instance
      .collection('users').snapshots();
}

The reason is so I can pass a initialData to the stream which I have in the format of List<int> so my screen isn't completely empty while it loads. So my options are either I convert the stream to a list or I convert my list to a QuerySnapshot. I think the former is much better.


Solution

  • You don't need to forcefully pass initialData, you can check when your snapshot is waiting to complete and add a default data there, like this:

    @override
    Widget build(BuildContext context) {
      return StreamBuilder<QuerySnapshot>(
        stream: FirebaseFirestore.instance.collection('users').snapshots(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            //Widget that is shown when there's an error in the snapshot.
            return const Text('Error');
          }
          List<int> myData = [];
          if (snapshot.connectionState == ConnectionState.waiting) {
            //Here fill your initialData
            myData = [1, 2, 3];
          } else {
            //Create a function that converts your snapshot in List<int>
            myData = _convertSnapshotToInt(snapshot.data);
          }
    
          return ChildThatUsesListInt(
            list: myData,
          );
        },
      );
    }