use of com.google.firebase.firestore.core.OrderBy in project firebase-android-sdk by firebase.
the class Query method boundFromDocumentSnapshot.
/**
* Create a Bound from a query given the document.
*
* <p>Note that the Bound will always include the key of the document and so only the provided
* document will compare equal to the returned position.
*
* <p>Will throw if the document does not contain all fields of the order by of the query or if
* any of the fields in the order by are an uncommitted server timestamp.
*/
private Bound boundFromDocumentSnapshot(String methodName, DocumentSnapshot snapshot, boolean inclusive) {
checkNotNull(snapshot, "Provided snapshot must not be null.");
if (!snapshot.exists()) {
throw new IllegalArgumentException("Can't use a DocumentSnapshot for a document that doesn't exist for " + methodName + "().");
}
Document document = snapshot.getDocument();
List<Value> components = new ArrayList<>();
// orders), multiple documents could match the position, yielding duplicate results.
for (OrderBy orderBy : query.getOrderBy()) {
if (orderBy.getField().equals(com.google.firebase.firestore.model.FieldPath.KEY_PATH)) {
components.add(Values.refValue(firestore.getDatabaseId(), document.getKey()));
} else {
Value value = document.getField(orderBy.getField());
if (ServerTimestamps.isServerTimestamp(value)) {
throw new IllegalArgumentException("Invalid query. You are trying to start or end a query using a document for which " + "the field '" + orderBy.getField() + "' is an uncommitted server timestamp. (Since the value of this field is " + "unknown, you cannot start/end a query with it.)");
} else if (value != null) {
components.add(value);
} else {
throw new IllegalArgumentException("Invalid query. You are trying to start or end a query using a document for which " + "the field '" + orderBy.getField() + "' (used as the orderBy) does not exist.");
}
}
}
return new Bound(components, inclusive);
}
use of com.google.firebase.firestore.core.OrderBy in project firebase-android-sdk by firebase.
the class Query method boundFromFields.
/**
* Converts a list of field values to Bound.
*/
private Bound boundFromFields(String methodName, Object[] values, boolean inclusive) {
// Use explicit order by's because it has to match the query the user made
List<OrderBy> explicitOrderBy = query.getExplicitOrderBy();
if (values.length > explicitOrderBy.size()) {
throw new IllegalArgumentException("Too many arguments provided to " + methodName + "(). The number of arguments must be less " + "than or equal to the number of orderBy() clauses.");
}
List<Value> components = new ArrayList<>();
for (int i = 0; i < values.length; i++) {
Object rawValue = values[i];
OrderBy orderBy = explicitOrderBy.get(i);
if (orderBy.getField().equals(com.google.firebase.firestore.model.FieldPath.KEY_PATH)) {
if (!(rawValue instanceof String)) {
throw new IllegalArgumentException("Invalid query. Expected a string for document ID in " + methodName + "(), but got " + rawValue + ".");
}
String documentId = (String) rawValue;
if (!query.isCollectionGroupQuery() && documentId.contains("/")) {
throw new IllegalArgumentException("Invalid query. When querying a collection and ordering by FieldPath.documentId(), " + "the value passed to " + methodName + "() must be a plain document ID, but '" + documentId + "' contains a slash.");
}
ResourcePath path = query.getPath().append(ResourcePath.fromString(documentId));
if (!DocumentKey.isDocumentKey(path)) {
throw new IllegalArgumentException("Invalid query. When querying a collection group and ordering by " + "FieldPath.documentId(), the value passed to " + methodName + "() must result in a valid document path, but '" + path + "' is not because it contains an odd number of segments.");
}
DocumentKey key = DocumentKey.fromPath(path);
components.add(Values.refValue(firestore.getDatabaseId(), key));
} else {
Value wrapped = firestore.getUserDataReader().parseQueryValue(rawValue);
components.add(wrapped);
}
}
return new Bound(components, inclusive);
}
use of com.google.firebase.firestore.core.OrderBy in project firebase-android-sdk by firebase.
the class RemoteSerializer method encodeQueryTarget.
public QueryTarget encodeQueryTarget(com.google.firebase.firestore.core.Target target) {
// Dissect the path into parent, collectionId, and optional key filter.
QueryTarget.Builder builder = QueryTarget.newBuilder();
StructuredQuery.Builder structuredQueryBuilder = StructuredQuery.newBuilder();
ResourcePath path = target.getPath();
if (target.getCollectionGroup() != null) {
hardAssert(path.length() % 2 == 0, "Collection Group queries should be within a document path or root.");
builder.setParent(encodeQueryPath(path));
CollectionSelector.Builder from = CollectionSelector.newBuilder();
from.setCollectionId(target.getCollectionGroup());
from.setAllDescendants(true);
structuredQueryBuilder.addFrom(from);
} else {
hardAssert(path.length() % 2 != 0, "Document queries with filters are not supported.");
builder.setParent(encodeQueryPath(path.popLast()));
CollectionSelector.Builder from = CollectionSelector.newBuilder();
from.setCollectionId(path.getLastSegment());
structuredQueryBuilder.addFrom(from);
}
// Encode the filters.
if (target.getFilters().size() > 0) {
structuredQueryBuilder.setWhere(encodeFilters(target.getFilters()));
}
// Encode the orders.
for (OrderBy orderBy : target.getOrderBy()) {
structuredQueryBuilder.addOrderBy(encodeOrderBy(orderBy));
}
// Encode the limit.
if (target.hasLimit()) {
structuredQueryBuilder.setLimit(Int32Value.newBuilder().setValue((int) target.getLimit()));
}
if (target.getStartAt() != null) {
Cursor.Builder cursor = Cursor.newBuilder();
cursor.addAllValues(target.getStartAt().getPosition());
cursor.setBefore(target.getStartAt().isInclusive());
structuredQueryBuilder.setStartAt(cursor);
}
if (target.getEndAt() != null) {
Cursor.Builder cursor = Cursor.newBuilder();
cursor.addAllValues(target.getEndAt().getPosition());
cursor.setBefore(!target.getEndAt().isInclusive());
structuredQueryBuilder.setEndAt(cursor);
}
builder.setStructuredQuery(structuredQueryBuilder);
return builder.build();
}
use of com.google.firebase.firestore.core.OrderBy in project firebase-android-sdk by firebase.
the class RemoteSerializer method decodeQueryTarget.
public com.google.firebase.firestore.core.Target decodeQueryTarget(String parent, StructuredQuery query) {
ResourcePath path = decodeQueryPath(parent);
String collectionGroup = null;
int fromCount = query.getFromCount();
if (fromCount > 0) {
hardAssert(fromCount == 1, "StructuredQuery.from with more than one collection is not supported.");
CollectionSelector from = query.getFrom(0);
if (from.getAllDescendants()) {
collectionGroup = from.getCollectionId();
} else {
path = path.append(from.getCollectionId());
}
}
List<Filter> filterBy;
if (query.hasWhere()) {
filterBy = decodeFilters(query.getWhere());
} else {
filterBy = Collections.emptyList();
}
List<OrderBy> orderBy;
int orderByCount = query.getOrderByCount();
if (orderByCount > 0) {
orderBy = new ArrayList<>(orderByCount);
for (int i = 0; i < orderByCount; i++) {
orderBy.add(decodeOrderBy(query.getOrderBy(i)));
}
} else {
orderBy = Collections.emptyList();
}
long limit = com.google.firebase.firestore.core.Target.NO_LIMIT;
if (query.hasLimit()) {
limit = query.getLimit().getValue();
}
Bound startAt = null;
if (query.hasStartAt()) {
startAt = new Bound(query.getStartAt().getValuesList(), query.getStartAt().getBefore());
}
Bound endAt = null;
if (query.hasEndAt()) {
endAt = new Bound(query.getEndAt().getValuesList(), !query.getEndAt().getBefore());
}
return new com.google.firebase.firestore.core.Target(path, collectionGroup, filterBy, orderBy, limit, startAt, endAt);
}
use of com.google.firebase.firestore.core.OrderBy in project firebase-android-sdk by firebase.
the class RemoteSerializer method decodeOrderBy.
private OrderBy decodeOrderBy(Order proto) {
FieldPath fieldPath = FieldPath.fromServerFormat(proto.getField().getFieldPath());
OrderBy.Direction direction;
switch(proto.getDirection()) {
case ASCENDING:
direction = Direction.ASCENDING;
break;
case DESCENDING:
direction = Direction.DESCENDING;
break;
default:
throw fail("Unrecognized direction %d", proto.getDirection());
}
return OrderBy.getInstance(direction, fieldPath);
}
Aggregations