Flutter StreamBuilder与实时数据库复制数据

时间:2020-06-30 00:50:01

标签: flutter firebase-realtime-database

我对实时数据库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]);
                            }
                        );
                      }
                  )
              ),
            ],
          ),
        );
      }

0 个答案:

没有答案