Skip to content

Commit 04479bd

Browse files
authored
Merge pull request #2527 from firebase/@invertase/import-script-alt-firestore
feat(firestore-bigquery-import-script): support non-default dbs
2 parents fb59dea + d1c29a0 commit 04479bd

File tree

9 files changed

+108
-205
lines changed

9 files changed

+108
-205
lines changed

firestore-bigquery-export/scripts/import/package-lock.json

Lines changed: 2 additions & 162 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

firestore-bigquery-export/scripts/import/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@firebaseextensions/fs-bq-import-collection",
3-
"version": "0.1.26",
3+
"version": "0.1.27",
44
"description": "Import a Firestore Collection into a BigQuery Changelog Table",
55
"main": "./lib/index.js",
66
"repository": {

firestore-bigquery-export/scripts/import/src/config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ const questions = [
8484
PROJECT_ID_MAX_CHARS
8585
),
8686
},
87+
{
88+
message:
89+
"What is your Firestore database instance ID? (Use '(default)' for the default database)",
90+
name: "firestoreInstanceId",
91+
type: "input",
92+
default: "(default)",
93+
},
8794
{
8895
message: "What is your BigQuery project ID?",
8996
name: "bigQueryProject",
@@ -271,10 +278,12 @@ export async function parseConfig(): Promise<CliConfig | CliConfigError> {
271278
cursorPositionFile,
272279
failedBatchOutput: program.failedBatchOutput,
273280
transformFunctionUrl: program.transformFunctionUrl,
281+
firestoreInstanceId: program.firestoreInstanceId || "(default)",
274282
};
275283
}
276284
const {
277285
project,
286+
firestoreInstanceId,
278287
sourceCollectionPath,
279288
bigQueryProject,
280289
dataset,
@@ -314,6 +323,7 @@ export async function parseConfig(): Promise<CliConfig | CliConfigError> {
314323
cursorPositionFile,
315324
failedBatchOutput,
316325
transformFunctionUrl,
326+
firestoreInstanceId: firestoreInstanceId || "(default)",
317327
};
318328
}
319329

firestore-bigquery-export/scripts/import/src/index.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
import { FirestoreBigQueryEventHistoryTracker } from "@firebaseextensions/firestore-bigquery-change-tracker";
1919
import * as firebase from "firebase-admin";
20+
import { getFirestore } from "firebase-admin/firestore";
2021
import * as fs from "fs";
2122
import * as util from "util";
2223

@@ -50,6 +51,7 @@ const run = async (): Promise<number> => {
5051
useEmulator,
5152
cursorPositionFile,
5253
transformFunctionUrl,
54+
firestoreInstanceId,
5355
} = config;
5456
if (useEmulator) {
5557
console.log("Using emulator");
@@ -63,14 +65,23 @@ const run = async (): Promise<number> => {
6365
// Initialize Firebase
6466
// This uses applicationDefault to authenticate
6567
// Please see https://cloud.google.com/docs/authentication/production
68+
let app: firebase.app.App;
6669
if (!firebase.apps.length) {
67-
firebase.initializeApp({
70+
app = firebase.initializeApp({
6871
projectId: projectId,
6972
credential: firebase.credential.applicationDefault(),
7073
databaseURL: `https://${projectId}.firebaseio.com`,
7174
});
75+
} else {
76+
app = firebase.app();
7277
}
7378

79+
// Get the Firestore instance for the specified database
80+
const db =
81+
firestoreInstanceId && firestoreInstanceId !== "(default)"
82+
? getFirestore(app, firestoreInstanceId)
83+
: getFirestore(app);
84+
7485
// We pass in the application-level "tableId" here. The tracker determines
7586
// the name of the raw changelog from this field.
7687
// TODO: fix this type, it should include clustering apparently
@@ -83,6 +94,7 @@ const run = async (): Promise<number> => {
8394
useNewSnapshotQuerySyntax,
8495
bqProjectId: bigQueryProjectId,
8596
transformFunction: transformFunctionUrl,
97+
firestoreInstanceId: firestoreInstanceId,
8698
});
8799

88100
await initializeDataSink(dataSink, config);
@@ -103,10 +115,10 @@ const run = async (): Promise<number> => {
103115

104116
if (await exists(cursorPositionFile)) {
105117
let cursorDocumentId = (await read(cursorPositionFile)).toString();
106-
cursor = await firebase.firestore().doc(cursorDocumentId).get();
118+
cursor = await db.doc(cursorDocumentId).get();
107119
logs.resumingImport(config, cursorDocumentId);
108120
}
109-
const totalRowsImported = await runSingleThread(dataSink, config, cursor);
121+
const totalRowsImported = await runSingleThread(dataSink, config, cursor, db);
110122
try {
111123
await unlink(cursorPositionFile);
112124
} catch (e) {

firestore-bigquery-export/scripts/import/src/program.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,10 @@ export const getCLIOptions = () => {
6565
.option(
6666
"-f, --failed-batch-output <file>",
6767
"Path to the JSON file where failed batches will be recorded."
68+
)
69+
.option(
70+
"--firestore-instance-id <database-id>",
71+
"The Firestore database instance ID. Use '(default)' for the default database.",
72+
"(default)"
6873
);
6974
};

firestore-bigquery-export/scripts/import/src/run-multi-thread.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as firebase from "firebase-admin";
2+
import { getFirestore } from "firebase-admin/firestore";
23
import { cpus } from "os";
34
import { pool } from "workerpool";
45
import * as logs from "./logs";
@@ -20,19 +21,24 @@ export async function runMultiThread(config: CliConfig): Promise<number> {
2021
PROJECT_ID: config.projectId,
2122
GOOGLE_CLOUD_PROJECT: config.projectId,
2223
GCLOUD_PROJECT: config.projectId,
24+
FIRESTORE_INSTANCE_ID: config.firestoreInstanceId,
2325
FAILED_BATCH_OUTPUT: config.failedBatchOutput || "",
2426
...process.env,
2527
},
2628
},
2729
});
2830

29-
const query = firebase
30-
.firestore()
31-
.collectionGroup(
32-
config.sourceCollectionPath.split("/")[
33-
config.sourceCollectionPath.split("/").length - 1
34-
]
35-
);
31+
const app = firebase.app();
32+
const db =
33+
config.firestoreInstanceId && config.firestoreInstanceId !== "(default)"
34+
? getFirestore(app, config.firestoreInstanceId)
35+
: getFirestore(app);
36+
37+
const query = db.collectionGroup(
38+
config.sourceCollectionPath.split("/")[
39+
config.sourceCollectionPath.split("/").length - 1
40+
]
41+
);
3642

3743
const partitionsList = query.getPartitions(config.batchSize);
3844

0 commit comments

Comments
 (0)