Skip to content

Commit

Permalink
Memoize firestore.getDatabase API calls when deploying Firestore func…
Browse files Browse the repository at this point in the history
…tions (#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
  • Loading branch information
taeold authored Dec 7, 2023
1 parent e644b4d commit 2d03226
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Fix bug where deploying Firestore function resulted in redudant API calls to the Firestore API (#6583).
- Fix an issue preventing Vite applications from being emulated on Windows. (#6411)
- Addressed an issue preventing Astro applications from being deployed from Windows. (#5709)
- Fixed an issue preventing Angular apps using ng-deploy from being emulated or deployed. (#6584)
Expand Down
20 changes: 19 additions & 1 deletion src/deploy/functions/services/firestore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,32 @@ import * as backend from "../backend";
import * as firestore from "../../../gcp/firestore";
import { FirebaseError } from "../../../error";

const dbCache = new Map<string, firestore.Database>();

/**
* A memoized version of firestore.getDatabase that avoids repeated calls to the API.
*
* @param project the project ID
* @param databaseId the database ID or "(default)"
*/
async function getDatabase(project: string, databaseId: string): Promise<firestore.Database> {
const key = `${project}/${databaseId}`;
if (dbCache.has(key)) {
return dbCache.get(key)!;
}
const db = await firestore.getDatabase(project, databaseId);
dbCache.set(key, db);
return db;
}

/**
* Sets a firestore event trigger's region to the firestore database region.
* @param endpoint the firestore endpoint
*/
export async function ensureFirestoreTriggerRegion(
endpoint: backend.Endpoint & backend.EventTriggered
): Promise<void> {
const db = await firestore.getDatabase(
const db = await getDatabase(
endpoint.project,
endpoint.eventTrigger.eventFilters?.database || "(default)"
);
Expand Down
2 changes: 1 addition & 1 deletion src/gcp/firestore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const apiClient = new Client({
urlPrefix: firestoreOrigin,
});

interface Database {
export interface Database {
name: string;
uid: string;
createTime: string;
Expand Down

0 comments on commit 2d03226

Please sign in to comment.