【问题标题】:Flutter Firestore paginationFlutter Firestore 分页
【发布时间】:2019-01-13 23:46:24
【问题描述】:

我正在尝试使用Firestore 进行分页,我阅读了文档并在Swift 中实现了这样的功能

let first = db.collection("cities")
    .order(by: "population")
    .limit(to: 25)

first.addSnapshotListener { (snapshot, error) in
    guard let snapshot = snapshot else {
        print("Error retrieving cities: \(error.debugDescription)")
        return
    }

    guard let lastSnapshot = snapshot.documents.last else {
        // The collection is empty.
        return
    }

    // Construct a new query starting after this document,
    // retrieving the next 25 cities.
    let next = db.collection("cities")
        .order(by: "population")
        .start(afterDocument: lastSnapshot)

    // Use the query for pagination.
    // ...
}

为了练习,我尝试获取三个文档,如果点击按钮,则再获取一个文档。

 Firestore.instance.collection('user').where('name', isEqualTo: 'Tom').orderBy('age').limit(3).getDocuments().then((snapshot) {
     _lastDocument = snapshot.documents.last;
     snapshot.documents.forEach((snap) {
        print(snap.data);
     });
   });

点击按钮后尝试这样。

 Firestore.instance.collection('user').where('name', isEqualTo: 'Tom').orderBy('age').startAfter(_lastDocument).limit(1).getDocuments().then((snapshot) {
     snapshot.documents.forEach((snap) {
        print(snap.data);
      });
     });

但是控制台这么说。

在处理手势时抛出以下断言:type “DocumentSnapshot”不是“List[dynamic]”类型的子类型

为什么我必须通过列表?

有谁知道如何解决这个问题?

更新

我可以这样分页。

class PaginationExample extends StatefulWidget {
  @override
  _PaginationExampleState createState() => _PaginationExampleState();
}

class _PaginationExampleState extends State<PaginationExample> {
  var _restaurants = <Restaurant>[];
  var _nomore = false;
  var _isFetching = false;
  DocumentSnapshot _lastDocument;
  ScrollController _controller;


  void _fetchDocuments() async {
    final QuerySnapshot querySnapshot = await Firestore.instance.collection('restaurants').orderBy('likes').limit(8).getDocuments();
    // your logic here
  }

  Future<Null> _fetchFromLast() async {
    final QuerySnapshot querySnapshot = await Firestore.instance.collection('restaurants').orderBy('likes').startAfter([_lastDocument['likes']]).limit(4).getDocuments();
      if (querySnapshot.documents.length < 4) {
          _nomore = true;
          return;
      }
      _lastDocument = querySnapshot.documents.last;
      for (final DocumentSnapshot snapshot in querySnapshot.documents) {
        final Restaurant re = Restaurant(snapshot);
        _restaurants.add(re);
      }
      setState(() {});
  }

  void _scrollListener() async {
    if (_nomore) return;
    if (_controller.position.pixels == _controller.position.maxScrollExtent && _isFetching == false) {
        _isFetching = true;
        await _fetchFromLast();
        _isFetching = false;
    }
  }

@override
  void initState() {
    _fetchDocuments();
    _controller = new ScrollController()..addListener(_scrollListener);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(

    );
  }
}

【问题讨论】:

  • 你从哪里得到这个错误?哪一行代码?
  • 我认为Firestore.instance.collection('user').where('name', isEqualTo: 'Tom').orderBy('age').startAfter(_lastDocument).limit(1).getDocuments() 在这里。 _lastDocument 导致错误

标签: google-cloud-firestore flutter


【解决方案1】:

仅使用 2 个属性进行分页,itemBuilderquery 使用此包 - paginate_firestore

例如,

      PaginateFirestore(
        itemBuilder: (context, documentSnapshot) => ListTile(
          leading: CircleAvatar(child: Icon(Icons.person)),
          title: Text(documentSnapshot.data['name']),
          subtitle: Text(documentSnapshot.documentID),
        ),
        // orderBy is compulsary to enable pagination
        query: Firestore.instance.collection('users').orderBy('name'),
      )

【讨论】:

  • 这个包正在从集合而不是 15 中获取所有记录。
【解决方案2】:

这里有错误:

     Firestore.instance.collection('user').where('name', isEqualTo: 'Tom').orderBy('age').startAfter(_lastDocument).limit(1).getDocuments().then((snapshot) {
         snapshot.documents.forEach((snap) {
            print(snap.data);
          });
         });

startAfter 方法需要一个 List 值参数,而您正在传递一个 DocumentSnapshot

获取 [values] 列表,创建并返回一个新的 [Query] 相对于查询的顺序,在提供的字段之后开始。

你可以试试这样的:

 Firestore.instance.collection('user').where('name', isEqualTo: 'Tom').orderBy('age').startAfter([{'name': 'Tom'}]).limit(1).getDocuments().then((snapshot) {
         snapshot.documents.forEach((snap) {
            print(snap.data);
          });
         });

【讨论】:

  • 非常感谢您的帮助,但仍然给我这个InvalidQueryException, Invalid query. You are trying to start or end a query using more values than were specified in the order by.)
  • 现在给我Invalid argument: Instance of 'DocumentSnapshot',我认为这是因为snapshot.documents.last 返回DocumentSnapshot。能说说怎么修吗?感谢您的帮助!
  • 这很奇怪,因为我正在阅读文档,它需要 startAfter 方法中的文档快照,但在 Flutter firestore sdk 中需要动态对象列表。
  • 是的。颤振说startAfter(List&lt;dynamic&gt; values) → Query cloud_firestore Takes a list of values, creates and returns a new Query that starts after the provided fields relative to the order of the query. The values must be in order of orderBy filters.
  • 对不起:.startAfter([{'name': 'Tom'}]]) 试试这个
猜你喜欢
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 2021-09-12
  • 2018-10-26
  • 1970-01-01
  • 2019-05-29
  • 2018-11-25
  • 2022-01-12
相关资源
最近更新 更多