Skip to content

Commit 2d03226

Browse files
authored
Memoize firestore.getDatabase API calls when deploying Firestore functions (#6583)
During deployment of a 2nd Gen Firestore functions, the CLI retrieves metadata associated with the Firestore database in order to ensure that the region of the Firestore database matches the region of the deployed function: https://github.com/firebase/firebase-tools/blob/1f4f6f494fd7a8a29887a8306930cda56aa7e13b/src/deploy/functions/services/firestore.ts#L9-L15 Unfortunately, when a large number of functions are deployed that each target a different Firestore instance (you are allowed to have multiple instances of Firestore on a single GCP project), developer will likely see a quota exceeds error: ``` Quota exceeded for quota metric 'Database operation requests' and limit 'Database Operations Per Minute' of service 'firestore.googleapis.com' for consumer ... ``` We mitigate the issue by memoizing the API calls. This should help with cases where multiple firestore functions are associated with a database, but wouldn't help if developer is setting up and deploying 60+ unique functions. Mitigates #6574
1 parent e644b4d commit 2d03226

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
- Fix bug where deploying Firestore function resulted in redudant API calls to the Firestore API (#6583).
12
- Fix an issue preventing Vite applications from being emulated on Windows. (#6411)
23
- Addressed an issue preventing Astro applications from being deployed from Windows. (#5709)
34
- Fixed an issue preventing Angular apps using ng-deploy from being emulated or deployed. (#6584)

src/deploy/functions/services/firestore.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,32 @@ import * as backend from "../backend";
22
import * as firestore from "../../../gcp/firestore";
33
import { FirebaseError } from "../../../error";
44

5+
const dbCache = new Map<string, firestore.Database>();
6+
7+
/**
8+
* A memoized version of firestore.getDatabase that avoids repeated calls to the API.
9+
*
10+
* @param project the project ID
11+
* @param databaseId the database ID or "(default)"
12+
*/
13+
async function getDatabase(project: string, databaseId: string): Promise<firestore.Database> {
14+
const key = `${project}/${databaseId}`;
15+
if (dbCache.has(key)) {
16+
return dbCache.get(key)!;
17+
}
18+
const db = await firestore.getDatabase(project, databaseId);
19+
dbCache.set(key, db);
20+
return db;
21+
}
22+
523
/**
624
* Sets a firestore event trigger's region to the firestore database region.
725
* @param endpoint the firestore endpoint
826
*/
927
export async function ensureFirestoreTriggerRegion(
1028
endpoint: backend.Endpoint & backend.EventTriggered
1129
): Promise<void> {
12-
const db = await firestore.getDatabase(
30+
const db = await getDatabase(
1331
endpoint.project,
1432
endpoint.eventTrigger.eventFilters?.database || "(default)"
1533
);

src/gcp/firestore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const apiClient = new Client({
88
urlPrefix: firestoreOrigin,
99
});
1010

11-
interface Database {
11+
export interface Database {
1212
name: string;
1313
uid: string;
1414
createTime: string;

0 commit comments

Comments
 (0)