orderBy method

Query orderBy(
  1. dynamic field, {
  2. bool descending = false,
})

Creates and returns a new Query that's additionally sorted by the specified field. The field may be a String representing a single field name or a FieldPath.

After a FieldPath.documentId order by call, you cannot add any more orderBy calls.

Furthermore, you may not use orderBy on the FieldPath.documentId field when using startAfterDocument, startAtDocument, endAfterDocument, or endAtDocument because the order by clause on the document id is added by these methods implicitly.

Implementation

Query orderBy(dynamic field, {bool descending = false}) {
  assert(field != null);
  _assertValidFieldType(field);
  assert(!_hasStartCursor(),
      'Invalid query. You must not call startAt(), startAtDocument(), startAfter() or startAfterDocument() before calling orderBy()');
  assert(!_hasEndCursor(),
      'Invalid query. You must not call endAt(), endAtDocument(), endBefore() or endBeforeDocument() before calling orderBy()');

  final List<List<dynamic>> orders =
      List<List<dynamic>>.from(parameters['orderBy']);

  assert(orders.where((List<dynamic> item) => field == item[0]).isEmpty,
      'OrderBy field "$field" already exists in this query');

  if (field == FieldPath.documentId) {
    orders.add([field, descending]);
  } else {
    FieldPath fieldPath =
        field is String ? FieldPath.fromString(field) : field;
    orders.add([fieldPath, descending]);
  }

  final List<List<dynamic>> conditions =
      List<List<dynamic>>.from(parameters['where']);

  if (conditions.isNotEmpty) {
    for (final dynamic condition in conditions) {
      dynamic field = condition[0];
      String operator = condition[1];

      // Initial orderBy() parameter has to match every where() fieldPath parameter when
      // inequality operator is invoked
      if (_isInequality(operator)) {
        assert(field == orders[0][0],
            'The initial orderBy() field "$orders[0][0]" has to be the same as the where() field parameter "$field" when an inequality operator is invoked.');
      }

      for (final dynamic order in orders) {
        dynamic orderField = order[0];

        // Any where() fieldPath parameter cannot match any orderBy() parameter when
        // '==' operand is invoked
        if (operator == '==') {
          assert(field != orderField,
              "The '$orderField' cannot be the same as your where() field parameter '$field'.");
        }

        if (field == FieldPath.documentId) {
          assert(orderField == FieldPath.documentId,
              "'[FieldPath.documentId]' cannot be used in conjunction with a different orderBy() parameter.");
        }
      }
    }
  }

  return Query._(firestore, _delegate.orderBy(orders));
}