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; }