Skip to content

Commit f538498

Browse files
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.
1 parent 4f58da2 commit f538498

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ See the section about [running tests](https://facebook.github.io/create-react-ap
8282
To run the test runner with emulators, use:
8383

8484
```bash
85-
firebase emulators:exec --project sample 'npm test'
85+
firebase emulators:exec --project demo-test 'npm test'
8686

87-
firebase emulators:exec --project sample --only firestore 'npm test AddCollectionDialog.test.tsx'
87+
firebase emulators:exec --project demo-test --only firestore 'npm test AddCollectionDialog.test.tsx'
8888
```
8989

9090
To disable the Jest interactive mode use the flag `watchAll=false` like so:
9191

9292
```bash
93-
firebase emulators:exec --project sample --only firestore 'npm test -- --watchAll=false'
93+
firebase emulators:exec --project demo-test --only firestore 'npm test -- --watchAll=false'
9494
```
9595

9696
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.

src/components/Firestore/Collection.test.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,33 @@ it('sorts documents when filtered', async () => {
232232
['doc-a', 'doc-b', 'doc-z']
233233
);
234234
});
235+
it('limits documents in a collection to specified value', async () => {
236+
const { queryAllByText, findByText } = await renderWithFirestore(
237+
async (firestore) => {
238+
const collectionRef = collection(firestore, 'my-stuff');
239+
await setDoc(doc(collectionRef, 'doc-z'), { foo: 'z' });
240+
await setDoc(doc(collectionRef, 'doc-a'), { foo: 'a' });
241+
await setDoc(doc(collectionRef, 'doc-b'), { foo: 'b' });
242+
243+
return (
244+
// Wrong props right?
245+
<>
246+
<Portal />
247+
<Collection
248+
collection={collectionRef}
249+
maxFetchedDocumentsPerCollection={2}
250+
/>
251+
</>
252+
);
253+
}
254+
);
255+
await findByText(/doc-a/);
256+
await findByText(/doc-b/);
257+
// The number of results is limited to 2 above, expect only a + b.
258+
expect(queryAllByText(/doc-a|doc-b|doc-z/).map((e) => e.textContent)).toEqual(
259+
['doc-a', 'doc-b']
260+
);
261+
});
235262

236263
it('shows the missing documents', async () => {
237264
const { getByText, findByText } = await renderWithFirestore(

src/components/Firestore/Collection.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
query,
3333
setDoc,
3434
where,
35+
limit
3536
} from 'firebase/firestore';
3637
import get from 'lodash.get';
3738
import React, { useEffect, useState } from 'react';
@@ -68,19 +69,21 @@ const NO_DOCS: QueryDocumentSnapshot<DocumentData>[] = [];
6869

6970
export interface Props {
7071
collection: CollectionReference;
72+
maxFetchedDocumentsPerCollection?: number;
7173
}
7274

7375
export function withCollectionState(
7476
Presentation: React.ComponentType<
7577
React.PropsWithChildren<CollectionPresentationProps>
7678
>
7779
): React.ComponentType<React.PropsWithChildren<Props>> {
78-
return ({ collection }) => {
80+
return ({ collection, maxFetchedDocumentsPerCollection }) => {
7981
const [newDocumentId, setNewDocumentId] = useState<string>();
8082
const collectionFilter = useCollectionFilter(collection.path);
8183
const filteredCollection = applyCollectionFilter(
8284
collection,
83-
collectionFilter
85+
collectionFilter,
86+
maxFetchedDocumentsPerCollection
8487
);
8588
const collectionSnapshot = useFirestoreCollection<{}>(filteredCollection, {
8689
suspense: true,
@@ -285,7 +288,8 @@ export const CollectionPresentation: React.FC<
285288

286289
function applyCollectionFilter(
287290
collection: Query<DocumentData>,
288-
collectionFilter?: CollectionFilterType
291+
collectionFilter?: CollectionFilterType,
292+
maxFetchedDocumentsPerCollection: number = 9500
289293
): Query<DocumentData> {
290294
let filteredCollection = collection;
291295
if (collectionFilter && isSingleValueCollectionFilter(collectionFilter)) {
@@ -314,6 +318,14 @@ function applyCollectionFilter(
314318
orderBy(collectionFilter.field, collectionFilter.sort)
315319
);
316320
}
321+
if (filteredCollection) {
322+
filteredCollection = query(
323+
filteredCollection,
324+
// This is a short-term fix to address the webchannel queue limit of 10k.
325+
// See https://github.com/firebase/firebase-tools/issues/5197.
326+
limit(maxFetchedDocumentsPerCollection)
327+
);
328+
}
317329
return filteredCollection;
318330
}
319331

0 commit comments

Comments
 (0)