From f53849806ed19ec755b8a39f8bcd57a39b186727 Mon Sep 17 00:00:00 2001
From: christhompsongoogle
<106194718+christhompsongoogle@users.noreply.github.com>
Date: Tue, 4 Apr 2023 14:33:19 -0700
Subject: [PATCH] Limited the number of documents in the collection viewer to
9500. (#935)
* Limited the number of documents in the collection viewer to 9500. This
is to resolve an issue where the Firestore emulator is hitting a 10k
webchannel queue limit.
* Lint
* Lint
* Update Collection.tsx
Removed a trailing comma on import list.
---
README.md | 6 ++---
src/components/Firestore/Collection.test.tsx | 27 ++++++++++++++++++++
src/components/Firestore/Collection.tsx | 18 ++++++++++---
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index 4afe57aa1..be5a5db47 100644
--- a/README.md
+++ b/README.md
@@ -82,15 +82,15 @@ See the section about [running tests](https://facebook.github.io/create-react-ap
To run the test runner with emulators, use:
```bash
-firebase emulators:exec --project sample 'npm test'
+firebase emulators:exec --project demo-test 'npm test'
-firebase emulators:exec --project sample --only firestore 'npm test AddCollectionDialog.test.tsx'
+firebase emulators:exec --project demo-test --only firestore 'npm test AddCollectionDialog.test.tsx'
```
To disable the Jest interactive mode use the flag `watchAll=false` like so:
```bash
-firebase emulators:exec --project sample --only firestore 'npm test -- --watchAll=false'
+firebase emulators:exec --project demo-test --only firestore 'npm test -- --watchAll=false'
```
If you get port conflict errors, make sure to stop other instances of the Firebase Emulator Suite (e.g. the one you've started for the development server above) and try again.
diff --git a/src/components/Firestore/Collection.test.tsx b/src/components/Firestore/Collection.test.tsx
index 1055375f2..00d9f7430 100644
--- a/src/components/Firestore/Collection.test.tsx
+++ b/src/components/Firestore/Collection.test.tsx
@@ -232,6 +232,33 @@ it('sorts documents when filtered', async () => {
['doc-a', 'doc-b', 'doc-z']
);
});
+it('limits documents in a collection to specified value', async () => {
+ const { queryAllByText, findByText } = await renderWithFirestore(
+ async (firestore) => {
+ const collectionRef = collection(firestore, 'my-stuff');
+ await setDoc(doc(collectionRef, 'doc-z'), { foo: 'z' });
+ await setDoc(doc(collectionRef, 'doc-a'), { foo: 'a' });
+ await setDoc(doc(collectionRef, 'doc-b'), { foo: 'b' });
+
+ return (
+ // Wrong props right?
+ <>
+
+
+ >
+ );
+ }
+ );
+ await findByText(/doc-a/);
+ await findByText(/doc-b/);
+ // The number of results is limited to 2 above, expect only a + b.
+ expect(queryAllByText(/doc-a|doc-b|doc-z/).map((e) => e.textContent)).toEqual(
+ ['doc-a', 'doc-b']
+ );
+});
it('shows the missing documents', async () => {
const { getByText, findByText } = await renderWithFirestore(
diff --git a/src/components/Firestore/Collection.tsx b/src/components/Firestore/Collection.tsx
index d21f57a21..6d1352205 100644
--- a/src/components/Firestore/Collection.tsx
+++ b/src/components/Firestore/Collection.tsx
@@ -32,6 +32,7 @@ import {
query,
setDoc,
where,
+ limit
} from 'firebase/firestore';
import get from 'lodash.get';
import React, { useEffect, useState } from 'react';
@@ -68,6 +69,7 @@ const NO_DOCS: QueryDocumentSnapshot[] = [];
export interface Props {
collection: CollectionReference;
+ maxFetchedDocumentsPerCollection?: number;
}
export function withCollectionState(
@@ -75,12 +77,13 @@ export function withCollectionState(
React.PropsWithChildren
>
): React.ComponentType> {
- return ({ collection }) => {
+ return ({ collection, maxFetchedDocumentsPerCollection }) => {
const [newDocumentId, setNewDocumentId] = useState();
const collectionFilter = useCollectionFilter(collection.path);
const filteredCollection = applyCollectionFilter(
collection,
- collectionFilter
+ collectionFilter,
+ maxFetchedDocumentsPerCollection
);
const collectionSnapshot = useFirestoreCollection<{}>(filteredCollection, {
suspense: true,
@@ -285,7 +288,8 @@ export const CollectionPresentation: React.FC<
function applyCollectionFilter(
collection: Query,
- collectionFilter?: CollectionFilterType
+ collectionFilter?: CollectionFilterType,
+ maxFetchedDocumentsPerCollection: number = 9500
): Query {
let filteredCollection = collection;
if (collectionFilter && isSingleValueCollectionFilter(collectionFilter)) {
@@ -314,6 +318,14 @@ function applyCollectionFilter(
orderBy(collectionFilter.field, collectionFilter.sort)
);
}
+ if (filteredCollection) {
+ filteredCollection = query(
+ filteredCollection,
+ // This is a short-term fix to address the webchannel queue limit of 10k.
+ // See https://github.com/firebase/firebase-tools/issues/5197.
+ limit(maxFetchedDocumentsPerCollection)
+ );
+ }
return filteredCollection;
}