Skip to content

Commit

Permalink
Limited the number of documents in the collection viewer to 9500. (#935)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
christhompsongoogle authored Apr 4, 2023
1 parent 4f58da2 commit f538498
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 6 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
27 changes: 27 additions & 0 deletions src/components/Firestore/Collection.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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?
<>
<Portal />
<Collection
collection={collectionRef}
maxFetchedDocumentsPerCollection={2}
/>
</>
);
}
);
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(
Expand Down
18 changes: 15 additions & 3 deletions src/components/Firestore/Collection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
query,
setDoc,
where,
limit
} from 'firebase/firestore';
import get from 'lodash.get';
import React, { useEffect, useState } from 'react';
Expand Down Expand Up @@ -68,19 +69,21 @@ const NO_DOCS: QueryDocumentSnapshot<DocumentData>[] = [];

export interface Props {
collection: CollectionReference;
maxFetchedDocumentsPerCollection?: number;
}

export function withCollectionState(
Presentation: React.ComponentType<
React.PropsWithChildren<CollectionPresentationProps>
>
): React.ComponentType<React.PropsWithChildren<Props>> {
return ({ collection }) => {
return ({ collection, maxFetchedDocumentsPerCollection }) => {
const [newDocumentId, setNewDocumentId] = useState<string>();
const collectionFilter = useCollectionFilter(collection.path);
const filteredCollection = applyCollectionFilter(
collection,
collectionFilter
collectionFilter,
maxFetchedDocumentsPerCollection
);
const collectionSnapshot = useFirestoreCollection<{}>(filteredCollection, {
suspense: true,
Expand Down Expand Up @@ -285,7 +288,8 @@ export const CollectionPresentation: React.FC<

function applyCollectionFilter(
collection: Query<DocumentData>,
collectionFilter?: CollectionFilterType
collectionFilter?: CollectionFilterType,
maxFetchedDocumentsPerCollection: number = 9500
): Query<DocumentData> {
let filteredCollection = collection;
if (collectionFilter && isSingleValueCollectionFilter(collectionFilter)) {
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit f538498

Please sign in to comment.