Skip to content

Commit 8473f73

Browse files
committed
feat(delete-user-data): add non-default firestore instance support
1 parent 2c6ca7e commit 8473f73

File tree

8 files changed

+41
-15
lines changed

8 files changed

+41
-15
lines changed

delete-user-data/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## Version 0.2.0
2+
3+
feat - add support for multiple Firestore databases via FIRESTORE_DATABASE_ID parameter
4+
15
## Version 0.1.24
26

37
feat - move to Node.js 20 runtimes

delete-user-data/PREINSTALL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Depending on where you'd like to delete user data from, make sure that you've se
1414

1515
Also, make sure that you've set up [Firebase Authentication](https://firebase.google.com/docs/auth) to manage your users.
1616

17+
**Note about multiple Firestore databases:** This extension supports using non-default Firestore databases. During installation, you can specify which database to use via the `FIRESTORE_DATABASE_ID` parameter. Use "(default)" for the default database, or specify your named database ID.
18+
1719
#### Billing
1820
To install an extension, your project must be on the [Blaze (pay as you go) plan](https://firebase.google.com/pricing)
1921

delete-user-data/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Depending on where you'd like to delete user data from, make sure that you've se
2222

2323
Also, make sure that you've set up [Firebase Authentication](https://firebase.google.com/docs/auth) to manage your users.
2424

25+
**Note about multiple Firestore databases:** This extension supports using non-default Firestore databases. During installation, you can specify which database to use via the `FIRESTORE_DATABASE_ID` parameter. Use "(default)" for the default database, or specify your named database ID.
26+
2527
#### Billing
2628
To install an extension, your project must be on the [Blaze (pay as you go) plan](https://firebase.google.com/pricing)
2729

@@ -37,6 +39,8 @@ To install an extension, your project must be on the [Blaze (pay as you go) plan
3739

3840
**Configuration Parameters:**
3941

42+
* Firestore Database ID: The ID of the Firestore database to use. Use "(default)" for the default database. You can view your available Firestore databases at https://console.cloud.google.com/firestore/databases.
43+
4044
* Cloud Firestore paths: Which paths in your Cloud Firestore instance contain data keyed on a user ID? Leave empty if you don't use Cloud Firestore.
4145
Enter the full paths, separated by commas. Use `{UID}` as a placeholder for the user's UID.
4246
For example, if you have the collections `users` and `admins`, and each collection has documents with User ID as document IDs, then enter `users/{UID},admins/{UID}`.

delete-user-data/extension.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
name: delete-user-data
16-
version: 0.1.24
16+
version: 0.2.0
1717
specVersion: v1beta
1818

1919
displayName: Delete User Data
@@ -86,6 +86,16 @@ resources:
8686
resource: projects/${PROJECT_ID}/topics/ext-${EXT_INSTANCE_ID}-deletion
8787

8888
params:
89+
- param: FIRESTORE_DATABASE_ID
90+
label: Firestore Database ID
91+
description: >-
92+
The ID of the Firestore database to use. Use "(default)" for the default
93+
database. You can view your available Firestore databases at
94+
https://console.cloud.google.com/firestore/databases.
95+
type: string
96+
default: (default)
97+
required: true
98+
8999
- param: FIRESTORE_PATHS
90100
label: Cloud Firestore paths
91101
description: >-

delete-user-data/functions/src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
export default {
1818
location: process.env.LOCATION,
19+
databaseId: process.env.FIRESTORE_DATABASE_ID || "(default)",
1920
firestorePaths: process.env.FIRESTORE_PATHS,
2021
firestoreDeleteMode: process.env.FIRESTORE_DELETE_MODE,
2122
rtdbPaths: process.env.RTDB_PATHS,

delete-user-data/functions/src/index.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
*/
1616

1717
import * as admin from "firebase-admin";
18-
import { FieldPath, DocumentReference } from "firebase-admin/firestore";
18+
import {
19+
FieldPath,
20+
DocumentReference,
21+
getFirestore,
22+
} from "firebase-admin/firestore";
1923
import * as functions from "firebase-functions";
2024
import { getDatabaseUrl, hasValidUserPath } from "./helpers";
2125
import chunk from "lodash.chunk";
@@ -40,7 +44,8 @@ admin.initializeApp({
4044
databaseURL,
4145
});
4246

43-
const db = admin.firestore();
47+
// Initialize Firestore with the configured database
48+
const db = getFirestore(config.databaseId);
4449

4550
/** Setup EventArc Channels */
4651
const eventChannel =
@@ -82,7 +87,7 @@ export const handleDeletion = functions.pubsub
8287
continue;
8388
}
8489
if (config.firestoreDeleteMode === "recursive") {
85-
await recursiveDelete(path);
90+
await recursiveDelete(path, db);
8691
} else {
8792
batch.delete(docRef);
8893
}
@@ -127,7 +132,7 @@ export const handleSearch = functions.pubsub
127132
if (depth <= config.searchDepth) {
128133
// If the collection ID is the same as the UID, delete the entire collection and sub-collections
129134
if (collection.id === uid) {
130-
await recursiveDelete(path);
135+
await recursiveDelete(path, db);
131136

132137
if (eventChannel) {
133138
/** Publish event to EventArc */
@@ -151,7 +156,7 @@ export const handleSearch = functions.pubsub
151156
documentReferences.map(async (reference) => {
152157
// Start a sub-collection search on each document.
153158
if (nextDepth <= config.searchDepth) {
154-
await search(uid, nextDepth, reference);
159+
await search(uid, nextDepth, db, reference);
155160
}
156161

157162
// If the ID of the document is the same as the UID, add it to delete list.
@@ -223,7 +228,7 @@ export const clearData = functions.auth.user().onDelete(async (user) => {
223228

224229
/** If search mode enable, run pubsub search fn */
225230
if (enableSearch) {
226-
await search(uid, 1);
231+
await search(uid, 1, db);
227232
}
228233

229234
/** If search function provided, return a list of queries */
@@ -316,19 +321,18 @@ const clearFirestoreData = async (firestorePaths: string, uid: string) => {
316321
const isRecursive = config.firestoreDeleteMode === "recursive";
317322

318323
if (!isRecursive) {
319-
const firestore = admin.firestore();
320324
logs.firestorePathDeleting(path, false);
321325

322326
// Wrapping in transaction to allow for automatic retries (#48)
323-
await firestore.runTransaction((transaction) => {
324-
transaction.delete(firestore.doc(path));
327+
await db.runTransaction((transaction) => {
328+
transaction.delete(db.doc(path));
325329
return Promise.resolve();
326330
});
327331
logs.firestorePathDeleted(path, false);
328332
} else {
329333
logs.firestorePathDeleting(path, true);
330334

331-
await recursiveDelete(path);
335+
await recursiveDelete(path, db);
332336

333337
logs.firestorePathDeleted(path, true);
334338
}

delete-user-data/functions/src/recursiveDelete.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import * as admin from "firebase-admin";
22

33
const MAX_RETRY_ATTEMPTS = 3;
44

5-
export const recursiveDelete = async (path: string) => {
6-
const db = admin.firestore();
5+
export const recursiveDelete = async (
6+
path: string,
7+
db: admin.firestore.Firestore
8+
) => {
79
// Recursively delete a reference and log the references of failures.
810
const bulkWriter = db.bulkWriter();
911

delete-user-data/functions/src/search.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ const { PubSub } = require("@google-cloud/pubsub");
55
export const search = async (
66
uid: string,
77
depth: number,
8+
db: admin.firestore.Firestore,
89
document?: admin.firestore.DocumentReference<admin.firestore.DocumentData>
910
) => {
10-
const db = admin.firestore();
11-
1211
const pubsub = new PubSub();
1312

1413
const topic = pubsub.topic(

0 commit comments

Comments
 (0)