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
,
Allow me to put forth my version of an RxDart solution. I use combineLatest2
with a ListView.builder
to build each message Widget. During the construction of each message Widget I lookup the name of the user with the corresponding uid
.
In this snippet I use a linear lookup for the user's name but that can be improved by creating a uid -> user name
map
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/widgets.dart';
import 'package:rxdart/rxdart.dart';
class MessageWidget extends StatelessWidget {
// final chatStream = Firestore.instance.collection('chat').snapshots();
// final userStream = Firestore.instance.collection('users').snapshots();
Stream chatStream;
Stream userStream;
MessageWidget(this.chatStream, this.userStream);
@override
Widget build(BuildContext context) {
Observable> combinedStream = Observable.combineLatest2(
chatStream, userStream, (messages, users) => [messages, users]);
return StreamBuilder(
stream: combinedStream,
builder: (_, AsyncSnapshot> snapshots) {
if (snapshots.hasData) {
List chats = snapshots.data[0].documents;
// It would be more efficient to convert this list of user documents
// to a map keyed on the uid which will allow quicker user lookup.
List users = snapshots.data[1].documents;
return ListView.builder(itemBuilder: (_, index) {
return Center(
child: Column(
children: [
Text(chats[index]['message']),
Text(getUserName(users, chats[index]['uid'])),
],
),
);
});
} else {
return Text('loading...');
}
});
}
// This does a linear search through the list of users. However a map
// could be used to make the finding of the user's name more efficient.
String getUserName(List users, String uid) {
for (final user in users) {
if (user['uid'] == uid) {
return user['name'];
}
}
return 'unknown';
}
}