Flutter-Firestore transform Stream<List<DocumentSnapshot<Map<String, dynamic>>>> into List<MyClass>

510
stream.listen((List<DocumentSnapshot> documentList) {
  // this function would be called when ever documentList changes.
  // So, it might be called even after your getClientsList() is completed.
  List<Map<String, dynamic>> newResult = documentList.map((e) => e.data()).toList();
});

Since getClientsList returns a future, you might want to convert the stream to a future. In that case, you can use this.

List<Map<String, dynamic>> newResult = (await stream.first).map((e) => e.data()).toList();

Alternatively, you can listen to the stream using a stream builder. Something like this.

StreamBuilder<DocumentSnapshot>(
  stream: _geo.collection(collectionRef: collectionReference)
      .within(center: center, radius: radius, field: field),
  builder:
      (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
    if (snapshot.hasError) return Text('Something went wrong');
    if (snapshot.connectionState == ConnectionState.waiting)
      return CircularProgressIndicator();

    List<Map<String, dynamic>> newResult = snapshot.data.data();
    print(newResult);
    return SizedBox();
  },
)
Share:
510
FLTY
Author by

FLTY

Updated on January 01, 2023

Comments

  • FLTY
    FLTY over 1 year

    I made a function where I want to return all places in my database which are inside a radius. Thats why Im using GeoFlutterFire. My problem its that I dont know how to convert Stream<List<DocumentSnapshot<Map<String, dynamic>>>> into a List<> of my Class type.

    
    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:geoflutterfire/geoflutterfire.dart';
    import 'package:firebase_auth/firebase_auth.dart';
    import 'package:firebase_storage/firebase_storage.dart';
    import 'package:uerto/models/index.dart';
    
    class SearchApi {
      const SearchApi({required FirebaseAuth auth, required FirebaseFirestore firestore, required FirebaseStorage storage, required Geoflutterfire geo})
          : _auth = auth,
            _firestore = firestore,
            _storage = storage,
            _geo = geo;
    
      final FirebaseAuth _auth;
      final FirebaseFirestore _firestore;
      final FirebaseStorage _storage;
      final Geoflutterfire _geo;
    
      Future<List<AppClient>> getClientList() async{
    
        final List<AppClient> newResult = <AppClient>[];
    
        final GeoFirePoint center = _geo.point(latitude: 44.414445, longitude: 26.01135501);
    
        final CollectionReference<Map<String, dynamic>> collectionReference = _firestore.collection('clients/London/Beauty');
    
        final double radius = 5000;
        const String field = 'point';
    
        final  Stream<List<DocumentSnapshot<Map<String, dynamic>>>> stream = _geo.collection(collectionRef: collectionReference).within(center: center, radius: radius, field: field);
    
        ///something to transform Stream<List<DocumentSnapshot<Map<String, dynamic>>>> stream into List<AppClient> result;
    
        newResult.addAll(result);
    
        return newResult;
    
      }
    }
    
    • Micah
      Micah almost 3 years
      Maybe just access a moment in the stream to grab one list at a time. Because your stream isn't a list. You could maybe chunk the stream into smaller list records, if you don't need it to stay in one object.
    • pskink
      pskink almost 3 years
      see Stream.first property for example - the docs say: "The first element of this stream. Stops listening to this stream after the first element has been received."