Home > Enterprise >  Query limitations in Firebase - .orderBy() error
Query limitations in Firebase - .orderBy() error

Time:12-18

I am trying to fetch data from a collection in Firebase using this method:

FirebaseFirestore.instance.collection('posts')                      
.where('datePublished', isGreaterThanOrEqualTo: 1)
.orderBy('datePublished')
.orderBy('votes', descending: true)

The problem is that the posts are now being listed by order of 'datePublished' but instead I want the list of posts to be ordered by 'votes'.

If I remove the .orderBy('datePublished') line, I'll receive this error (Here is the documentation reference from that error message if it can be of more help):

error 'package:cloud_firestore/src/query.dart': Failed assertion: line 487 pos 13: 'conditionField == orders[0][0]': The initial orderBy() field "[[FieldPath([votes]), true]][0][0]" has to be the same as the where() field parameter "FieldPath([datePublished])" when an inequality operator is invoked. #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61)

Any help appreciated, thanks!

CodePudding user response:

Try the following code:

Stream<List<T>> collectionStream<T>({
  required String path,
  required T Function(Map<String, dynamic> data, String documentId) builder,
  Query<Object?> Function(Query query)? queryBuilder,
  bool Function(T)? where,
}) {
  Query<Object?> query = firestore.collection(path);
  if (queryBuilder != null) {
    query = queryBuilder(query);
  }
  Stream<QuerySnapshot<Object?>> snapshots = query.snapshots();
  return snapshots.map((snapshot) {
    List<T> result = snapshot.docs.map((snapshot) => builder(snapshot.data() as Map<String, dynamic>, snapshot.id)).where((value) => value != null).toList();
    if (where != null) {
      result.where(where);
    }
    return result;
  });
}

class Model {
  Model(this.id, this.datePublished, this.votes);

  final String id;
  final int datePublished;
  final int votes;

  factory Model.fromMap(Map<String, dynamic> data, String documentId) {
    final String? datePublished = data["datePublished"];
    final String? votes = data["votes"];

    return Model(documentId, datePublished ?? 0, votes ?? 0);
  }

  Map<String, dynamic> toMap() => {"datePublished": datePublished, "votes": votes};
}

collectionStream(
  path: "posts",
  queryBuilder: (query) => query.orderBy('votes', descending: true),
  builder: (data, documentId) => Model.fromMap(data, documentId),
  where: (model) => model.datePublished >= 94,
),
  • Related