我对实时数据库Firebase有问题,我试图在用户每次滚动到按钮时应用加载新帖子时在Instagram上实现类似的逻辑。我现在只有3篇文章,并尝试通过2次加载来加载它们,最初在用户点击底部时获取。第一个请求是当应用程序启动时我收到2条帖子,后来用户向下滚动时我收到3条帖子,即使我设置了 startAt 查询,它应该只有一个,但它会返回旧数据的副本。 / p>
ItemPost lastPostInit;
ItemPost lastPostPaganation = ItemPost(null);
List<ItemPost> firstPageItems = List<ItemPost>();
List<ItemPost> recicleItems = List<ItemPost>();
ScrollController listScrollController;
final _list = List<ItemPost>();
final _listController = StreamController<List<ItemPost>>.broadcast();
Stream<List<ItemPost>> get listStream => _listController.stream;
@override
void initState() {
super.initState();
Admob.initialize(adMobService.getAdMobAppId());
_onReomveSubscription = databaseReference.reference().child('PublicPosts').onChildRemoved.listen((v){
setState(() {
});
});
listScrollController = new ScrollController()..addListener(_scrollListener);
_firstFeth();
}
void _scrollListener() async {
if (listScrollController.position.pixels ==
listScrollController.position.maxScrollExtent) {
_fetchMore();
}
}
firstFeth(){
FirebaseDatabase.instance
.reference()
.child("PublicPosts")
.orderByChild('Created')
.limitToFirst(3)
.once()
.then((snapshot) {
Map<dynamic, dynamic> map = snapshot.value;
if(map != null){
List<dynamic> list = map.values.toList()..sort((a, b) => b['Created'].compareTo(a['Created']));
Map<dynamic, dynamic> ma = list.toList().asMap();
firstPageItems = List<ItemPost>();
ma.forEach((key, value) {
firstPageItems.add(ItemPost.fromJsonSorted(key, value));
});
}
lastPostInit = firstPageItems.last;
lastPostPaganation.created = 0;
firstPageItems.removeLast();
_list.addAll(firstPageItems);
_listController.sink.add(_list);
});
}
_fetchMore() {
// Returning 3 elements but should be one since I have only 3 posts in databese
FirebaseDatabase.instance
.reference()
.child("PublicPosts")
.orderByChild('Created')
.startAt(lastPostInit.created)
.limitToFirst(8)
.once()
.then((snapshot) {
// Sorting by timestamp created int
Map<dynamic, dynamic> map = snapshot.value;
if(map != null){
List<dynamic> list = map.values.toList()..sort((a, b) => b['Created'].compareTo(a['Created']));
Map<dynamic, dynamic> ma = list.toList().asMap();
recicleItems = List<ItemPost>();
ma.forEach((key, value) {
recicleItems.add(ItemPost.fromJsonSorted(key, value));
});
}
recicleItems.remove(lastPostInit);
lastPostInit = recicleItems.last;
//Compering last created timestamp with old to avoid infinite list
if(lastPostInit.created != lastPostPaganation.created){
lastPostPaganation = recicleItems.last;
_list.addAll(recicleItems);
List<ItemPost> listSorted = LinkedHashSet<ItemPost>.from(_list).toList();
_listController.sink.add(listSorted);
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF231f22),
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Color(0xFF231f22),
title: Text(
"Social",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 26, color: Colors.white),
),
),
body: Column(
children: <Widget>[
AdmobBanner(
adSize: AdmobBannerSize.FULL_BANNER,
adUnitId: adMobService.getBannerAdId(),
),
Flexible(
child: StreamBuilder<List<ItemPost>>(
stream: listStream,
builder: (context, snapshot) {
return ListView.builder(
itemCount: (snapshot.data != null)?snapshot.data.length:0,
controller: listScrollController,
shrinkWrap: true,
itemBuilder: (context, index) {
return socialItem(snapshot.data[index]);
}
);
}
)
),
],
),
);
}