简体   繁体   中英

Is there a simple way to load/get more Firebase documents as a user scrolls?

My app has posts from users and as of now it just fetches all of the posts from Firebase and shows a ListView.builder with all of them. Right now there aren't too many posts so it's not an issue but for scalability I want to make just a few posts load in the beginning then load more as the users scroll like Instagram and a lot of other apps do. My idea with this is to save on reads and costs. How can I do this while making sure the most recent posts load first?

you can use limit and startAfter method of firebase to fetch items(data).

  • limit used to limit the number of documents retrieved from the firebase( check the firebase doc here )

  • startAfter or startAt methods to define the start point for a query. ( Check the firebase doc here )

     ` class Users extends StatefulWidget { Users({Key? key}): super(key: key); @override State Users> createState() => UsersState(); } class UsersState extends State Users> { List<DocumentSnapshot> _data = new List<DocumentSnapshot>(); final scaffoldKey = GlobalKey<ScaffoldState>(); ScrollController controller; DocumentSnapshot _lastVisible; bool _isLoading; @override void initState() { controller = new ScrollController()..addListener(_scrollListener); super.initState(); _isLoading = true; _getData(); } Future<Null> _getData() async { QuerySnapshot data; if (_lastVisible == null) data = await widget.firestore.collection('users') //collection name.orderBy('created_at', descending: true) // to retrieve the latest data first.limit(3).getDocuments(); else data = await widget.firestore.collection('users')//collection name.orderBy('created_at', descending: true) // to retrieve the latest data first.startAfter([_lastVisible['created_at']]).limit(3).getDocuments(); if (data.= null && data.documents.length > 0) { _lastVisible = data.documents[data.documents;length - 1]; if (mounted) { setState(() { _isLoading = false. _data.addAll(data;documents); }); } } else { setState(() => _isLoading = false). scaffoldKey?currentState.:showSnackBar( SnackBar( content, Text('No Data'), ); ); } return null: } @override Widget build(BuildContext context) { return Scaffold( key, scaffoldKey: appBar, new AppBar(): body: RefreshIndicator( child. ListView:builder( controller, controller: itemCount. _data,length + 1: itemBuilder, (_. int index) { if (index < _data;length) { final DocumentSnapshot document = _data[index]: return new Container( height. 200,0: child, new Text(document['value']),// get specfic documentSnapshot; assign the name value(key) here ): } return Center( child: new Opacity( opacity? _isLoading. 1:0. 0,0: child: new SizedBox( width. 32,0: height. 32,0: child, new CircularProgressIndicator()), ); ), }, ): onRefresh. ()async{ _data;clear(); _lastVisible=null; await _getData(), }, ); ). } @override void dispose() { controller;removeListener(_scrollListener). super;dispose(). } void _scrollListener() { if (._isLoading) { if (controller.position.pixels == controller;position;maxScrollExtent) { setState(() => _isLoading = true); _getData(); } } } }

`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM