Skip to content

Public Count #4130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions firebase-firestore/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ package com.google.firebase {

package com.google.firebase.firestore {

public class AggregateQuery {
method @NonNull public com.google.android.gms.tasks.Task<com.google.firebase.firestore.AggregateQuerySnapshot> get(@NonNull com.google.firebase.firestore.AggregateSource);
method @NonNull public com.google.firebase.firestore.Query getQuery();
}

public class AggregateQuerySnapshot {
method public long getCount();
method @NonNull public com.google.firebase.firestore.AggregateQuery getQuery();
}

public enum AggregateSource {
enum_constant public static final com.google.firebase.firestore.AggregateSource SERVER;
}

public class Blob implements java.lang.Comparable<com.google.firebase.firestore.Blob> {
method public int compareTo(@NonNull com.google.firebase.firestore.Blob);
method @NonNull public static com.google.firebase.firestore.Blob fromBytes(@NonNull byte[]);
Expand Down Expand Up @@ -290,6 +304,7 @@ package com.google.firebase.firestore {
method @NonNull public com.google.firebase.firestore.ListenerRegistration addSnapshotListener(@NonNull com.google.firebase.firestore.MetadataChanges, @NonNull com.google.firebase.firestore.EventListener<com.google.firebase.firestore.QuerySnapshot>);
method @NonNull public com.google.firebase.firestore.ListenerRegistration addSnapshotListener(@NonNull java.util.concurrent.Executor, @NonNull com.google.firebase.firestore.MetadataChanges, @NonNull com.google.firebase.firestore.EventListener<com.google.firebase.firestore.QuerySnapshot>);
method @NonNull public com.google.firebase.firestore.ListenerRegistration addSnapshotListener(@NonNull android.app.Activity, @NonNull com.google.firebase.firestore.MetadataChanges, @NonNull com.google.firebase.firestore.EventListener<com.google.firebase.firestore.QuerySnapshot>);
method @NonNull public com.google.firebase.firestore.AggregateQuery count();
method @NonNull public com.google.firebase.firestore.Query endAt(@NonNull com.google.firebase.firestore.DocumentSnapshot);
method @NonNull public com.google.firebase.firestore.Query endAt(java.lang.Object...);
method @NonNull public com.google.firebase.firestore.Query endBefore(@NonNull com.google.firebase.firestore.DocumentSnapshot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ public void testCanRunCount() {
"b", map("k", "b"),
"c", map("k", "c")));

AggregateQuerySnapshot snapshot =
waitFor(collection.count().get(AggregateSource.SERVER_DIRECT));
AggregateQuerySnapshot snapshot = waitFor(collection.count().get(AggregateSource.SERVER));
assertEquals(Long.valueOf(3), snapshot.getCount());
}

Expand All @@ -103,7 +102,7 @@ public void testCanRunCountWithFilters() {
"c", map("k", "c")));

AggregateQuerySnapshot snapshot =
waitFor(collection.whereEqualTo("k", "b").count().get(AggregateSource.SERVER_DIRECT));
waitFor(collection.whereEqualTo("k", "b").count().get(AggregateSource.SERVER));
assertEquals(Long.valueOf(1), snapshot.getCount());
}

Expand All @@ -118,7 +117,7 @@ public void testCanRunCountWithOrderBy() {
"d", map("absent", "d")));

AggregateQuerySnapshot snapshot =
waitFor(collection.orderBy("k").count().get(AggregateSource.SERVER_DIRECT));
waitFor(collection.orderBy("k").count().get(AggregateSource.SERVER));
// "d" is filtered out because it is ordered by "k".
assertEquals(Long.valueOf(3), snapshot.getCount());
}
Expand All @@ -132,7 +131,7 @@ public void testTerminateDoesNotCrashWithFlyingCountQuery() {
"b", map("k", "b"),
"c", map("k", "c")));

collection.orderBy("k").count().get(AggregateSource.SERVER_DIRECT);
collection.orderBy("k").count().get(AggregateSource.SERVER);
waitFor(collection.firestore.terminate());
}

Expand All @@ -146,15 +145,15 @@ public void testSnapshotEquals() {
"c", map("k", "c")));

AggregateQuerySnapshot snapshot1 =
waitFor(collection.whereEqualTo("k", "b").count().get(AggregateSource.SERVER_DIRECT));
waitFor(collection.whereEqualTo("k", "b").count().get(AggregateSource.SERVER));
AggregateQuerySnapshot snapshot1_same =
waitFor(collection.whereEqualTo("k", "b").count().get(AggregateSource.SERVER_DIRECT));
waitFor(collection.whereEqualTo("k", "b").count().get(AggregateSource.SERVER));

AggregateQuerySnapshot snapshot2 =
waitFor(collection.whereEqualTo("k", "a").count().get(AggregateSource.SERVER_DIRECT));
waitFor(collection.whereEqualTo("k", "a").count().get(AggregateSource.SERVER));
waitFor(collection.document("d").set(map("k", "a")));
AggregateQuerySnapshot snapshot2_different =
waitFor(collection.whereEqualTo("k", "a").count().get(AggregateSource.SERVER_DIRECT));
waitFor(collection.whereEqualTo("k", "a").count().get(AggregateSource.SERVER));

assertTrue(snapshot1.equals(snapshot1_same));
assertEquals(snapshot1.hashCode(), snapshot1_same.hashCode());
Expand Down Expand Up @@ -196,7 +195,7 @@ public void testCanRunCollectionGroupQuery() {
waitFor(batch.commit());

AggregateQuerySnapshot snapshot =
waitFor(db.collectionGroup(collectionGroup).count().get(AggregateSource.SERVER_DIRECT));
waitFor(db.collectionGroup(collectionGroup).count().get(AggregateSource.SERVER));
assertEquals(
Long.valueOf(5), // "cg-doc1", "cg-doc2", "cg-doc3", "cg-doc4", "cg-doc5",
snapshot.getCount());
Expand All @@ -213,17 +212,12 @@ public void testCanRunCountWithFiltersAndLimits() {
"d", map("k", "d")));

AggregateQuerySnapshot snapshot =
waitFor(
collection.whereEqualTo("k", "a").limit(2).count().get(AggregateSource.SERVER_DIRECT));
waitFor(collection.whereEqualTo("k", "a").limit(2).count().get(AggregateSource.SERVER));
assertEquals(Long.valueOf(2), snapshot.getCount());

snapshot =
waitFor(
collection
.whereEqualTo("k", "a")
.limitToLast(2)
.count()
.get(AggregateSource.SERVER_DIRECT));
collection.whereEqualTo("k", "a").limitToLast(2).count().get(AggregateSource.SERVER));
assertEquals(Long.valueOf(2), snapshot.getCount());

snapshot =
Expand All @@ -232,20 +226,18 @@ public void testCanRunCountWithFiltersAndLimits() {
.whereEqualTo("k", "d")
.limitToLast(1000)
.count()
.get(AggregateSource.SERVER_DIRECT));
.get(AggregateSource.SERVER));
assertEquals(Long.valueOf(1), snapshot.getCount());
}

@Test
public void testCanRunCountOnNonExistentCollection() {
CollectionReference collection = testFirestore().collection("random-coll");

AggregateQuerySnapshot snapshot =
waitFor(collection.count().get(AggregateSource.SERVER_DIRECT));
AggregateQuerySnapshot snapshot = waitFor(collection.count().get(AggregateSource.SERVER));
assertEquals(Long.valueOf(0), snapshot.getCount());

snapshot =
waitFor(collection.whereEqualTo("k", 100).count().get(AggregateSource.SERVER_DIRECT));
snapshot = waitFor(collection.whereEqualTo("k", 100).count().get(AggregateSource.SERVER));
assertEquals(Long.valueOf(0), snapshot.getCount());
}

Expand All @@ -259,14 +251,13 @@ public void testFailWithoutNetwork() {
"c", map("k", "c")));
waitFor(collection.getFirestore().disableNetwork());

Exception e = waitForException(collection.count().get(AggregateSource.SERVER_DIRECT));
Exception e = waitForException(collection.count().get(AggregateSource.SERVER));
assertThat(e, instanceOf(FirebaseFirestoreException.class));
assertEquals(
FirebaseFirestoreException.Code.UNAVAILABLE, ((FirebaseFirestoreException) e).getCode());

waitFor(collection.getFirestore().enableNetwork());
AggregateQuerySnapshot snapshot =
waitFor(collection.count().get(AggregateSource.SERVER_DIRECT));
AggregateQuerySnapshot snapshot = waitFor(collection.count().get(AggregateSource.SERVER));
assertEquals(Long.valueOf(3), snapshot.getCount());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* in test mocks. Subclassing is not supported in production code and new SDK releases may break
* code that does so.
*/
class AggregateQuery {
public class AggregateQuery {
// The base query.
private final Query query;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import static com.google.firebase.firestore.util.Preconditions.checkNotNull;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Objects;

/**
Expand All @@ -27,7 +26,7 @@
* in test mocks. Subclassing is not supported in production code and new SDK releases may break
* code that does so.
*/
class AggregateQuerySnapshot {
public class AggregateQuerySnapshot {

private final long count;
private final AggregateQuery query;
Expand All @@ -44,12 +43,8 @@ public AggregateQuery getQuery() {
return query;
}

/**
* @return The result of a document count aggregation. Returns null if no count aggregation is
* available in the result.
*/
@Nullable
public Long getCount() {
/** @return The result of a document count aggregation. */
public long getCount() {
return count;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
package com.google.firebase.firestore;

/** Configures the behavior of {@link AggregateQuery#get}. */
enum AggregateSource {
public enum AggregateSource {
/**
* Reach to the Firestore backend and surface the result verbatim, that is no local documents or
* mutations in the SDK cache will be included in the surfaced result.
*
* <p>Requires client to be online.
*/
SERVER_DIRECT,
SERVER,
}
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@ private void validateHasExplicitOrderByForLimitToLast() {
* the result set of this query.
*/
@NonNull
AggregateQuery count() {
public AggregateQuery count() {
return new AggregateQuery(this);
}

Expand Down