Я пытаюсь создать базовую функцию чата c, в которой все сообщения чата пользователей хранятся в виде документов в коллекции чатов. Я успешно реализовал разбиение на страницы, чтобы не перегружать данные, пока пользователь не выполнит прокрутку.
Однако, хотя у меня есть StreamBuilder, новые документы чата не появляются автоматически, как обычно. Почему Streambuilder не регистрирует и не отображает эти новые сообщения?
Вот мой код:
class MotivatorChat extends StatefulWidget {
@override
_MotivatorChatState createState() => _MotivatorChatState();
}
class _MotivatorChatState extends State<MotivatorChat> {
Firestore firestore = Firestore.instance;
List<DocumentSnapshot> chats = [];
bool isLoading = false;
bool hasMore = true;
int documentLimit = 10;
DocumentSnapshot lastDocument;
ScrollController _scrollController = ScrollController();
StreamController<List<DocumentSnapshot>> _controller = StreamController<List<DocumentSnapshot>>();
Stream<List<DocumentSnapshot>> get _streamController => _controller.stream;
@override
void initState() {
super.initState();
getChats();
_scrollController.addListener(() {
double maxScroll = _scrollController.position.maxScrollExtent;
double currentScroll = _scrollController.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.20;
if (maxScroll - currentScroll <= delta) {
getChats();
}
});
}
getChats() async {
if (!hasMore) {
print('No More Chats');
return;
}
if (isLoading) {
return;
}
setState(() {
isLoading = true;
});
QuerySnapshot querySnapshot;
if (lastDocument == null) {
querySnapshot = await firestore
.collection('chats')
.orderBy('timestamp', descending: true)
.limit(documentLimit)
.getDocuments();
} else {
querySnapshot = await firestore
.collection('chats')
.orderBy('timestamp', descending: true)
.startAfterDocument(lastDocument)
.limit(documentLimit)
.getDocuments();
print(1);
}
if (querySnapshot.documents.length < documentLimit) {
hasMore = false;
}
lastDocument = querySnapshot.documents[querySnapshot.documents.length - 1];
chats.addAll(querySnapshot.documents);
_controller.sink.add(chats);
setState(() {
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Pagination with Firestore'),
),
body: Column(children: [
Expanded(
child: StreamBuilder<List<DocumentSnapshot>>(
stream: _streamController,
builder: (sContext, snapshot) {
print(snapshot.connectionState);
if (snapshot.hasData && snapshot.data.length > 0) {
return ListView.builder(
reverse: true,
controller: _scrollController,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(top: 20),
child: Container(
height: 20,
child: Text(snapshot.data[index].data['text']),
),
);
},
);
} else {
return Center(
child: Text('No Data...'),
);
}
},
),
),
isLoading
? Container(
width: MediaQuery
.of(context)
.size
.width,
padding: EdgeInsets.all(5),
color: Colors.yellowAccent,
child: Text(
'Loading',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
)
: Container(),
]),
);
}
}
Обновлен StreamBuilder
StreamBuilder<List<DocumentSnapshot>>(
stream: _streamController,
builder: (sContext, snapshot) {
if (snapshot.connectionState == ConnectionState.none) {
return Text("None");
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
} else if (snapshot.connectionState == ConnectionState.active) {
if (snapshot.hasData && snapshot.data.length > 0) {
return ListView.builder(
reverse: true,
controller: _scrollController,
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(top: 20),
child: Container(
height: 20,
child: Text(snapshot.data[index].data['text']),
),
);
},
);
} else {
return Center(
child: Text('No Data...'),
);
}
} else {
return Text("return list");
}
},
),