Placing a Firebase Stream in a method

Issue

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,
      );
    },
  );
}

Answered By – Kentukyyo

Answer Checked By – Jay B. (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *