How do I join data from two Firestore collections in Flutter?

前端 未结 6 873
名媛妹妹
名媛妹妹 2020-11-29 02:27

I have a chat app in Flutter using Firestore, and I have two main collections:

  • chats, which is keyed on auto-ids, and has message,
6条回答
  •  醉话见心
    2020-11-29 02:54

    You can do it with RxDart like that.. https://pub.dev/packages/rxdart

    import 'package:rxdart/rxdart.dart';
    
    class Messages {
      final String messages;
      final DateTime timestamp;
      final String uid;
      final DocumentReference reference;
    
      Messages.fromMap(Map map, {this.reference})
          : messages = map['messages'],
            timestamp = (map['timestamp'] as Timestamp)?.toDate(),
            uid = map['uid'];
    
      Messages.fromSnapshot(DocumentSnapshot snapshot)
          : this.fromMap(snapshot.data, reference: snapshot.reference);
    
      @override
      String toString() {
        return 'Messages{messages: $messages, timestamp: $timestamp, uid: $uid, reference: $reference}';
      }
    }
    
    class Users {
      final String name;
      final DocumentReference reference;
    
      Users.fromMap(Map map, {this.reference})
          : name = map['name'];
    
      Users.fromSnapshot(DocumentSnapshot snapshot)
          : this.fromMap(snapshot.data, reference: snapshot.reference);
    
      @override
      String toString() {
        return 'Users{name: $name, reference: $reference}';
      }
    }
    
    class CombineStream {
      final Messages messages;
      final Users users;
    
      CombineStream(this.messages, this.users);
    }
    
    Stream> _combineStream;
    
    @override
      void initState() {
        super.initState();
        _combineStream = Observable(Firestore.instance
            .collection('chat')
            .orderBy("timestamp", descending: true)
            .snapshots())
            .map((convert) {
          return convert.documents.map((f) {
    
            Stream messages = Observable.just(f)
                .map((document) => Messages.fromSnapshot(document));
    
            Stream user = Firestore.instance
                .collection("users")
                .document(f.data['uid'])
                .snapshots()
                .map((document) => Users.fromSnapshot(document));
    
            return Observable.combineLatest2(
                messages, user, (messages, user) => CombineStream(messages, user));
          });
        }).switchMap((observables) {
          return observables.length > 0
              ? Observable.combineLatestList(observables)
              : Observable.just([]);
        })
    }
    

    for rxdart 0.23.x

    @override
          void initState() {
            super.initState();
            _combineStream = Firestore.instance
                .collection('chat')
                .orderBy("timestamp", descending: true)
                .snapshots()
                .map((convert) {
              return convert.documents.map((f) {
    
                Stream messages = Stream.value(f)
                    .map((document) => Messages.fromSnapshot(document));
    
                Stream user = Firestore.instance
                    .collection("users")
                    .document(f.data['uid'])
                    .snapshots()
                    .map((document) => Users.fromSnapshot(document));
    
                return Rx.combineLatest2(
                    messages, user, (messages, user) => CombineStream(messages, user));
              });
            }).switchMap((observables) {
              return observables.length > 0
                  ? Rx.combineLatestList(observables)
                  : Stream.value([]);
            })
        }
    

提交回复
热议问题