【发布时间】:2020-05-28 20:36:54
【问题描述】:
我正在尝试构建一个基本的聊天功能,其中所有用户聊天消息都作为文档存储在“聊天”集合中。我已经成功实现了分页,以确保在用户滚动之前不会过度提取数据。
但是,即使我有一个 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");
}
},
),
【问题讨论】:
-
使用
snapshot.connectionState查看。 -
@JohnJoe 连接状态是活动的,但仍未触发流添加新消息。
-
请粘贴您的最新代码。
-
@JohnJoe 更新了!
-
我没有看到你在某处使用
connectionState.active。
标签: flutter google-cloud-firestore