My answer is heavily inspired by @Geoffrey Bourne's answer, but I had to modify some stuff and figure out more details to get it working.
First, I upload the exportFirestore to Cloud Functions (production). When I run it through this URL https://us-central1-<project-id>.cloudfunctions.net/exportFirestore, I get a file DOWNLOADED, as Cloud Functions are read-only
The below code is for one collection named fl_content, I'll consider expanding it to multiple collections
export const exportFirestore = functions.https.onRequest(async (req, res) => { const collection = "fl_content"; const exportedData: any = {}; exportedData[collection] = {}; await admin .firestore() .collection(collection) .get() .then((snapshot) => snapshot.forEach((doc) => exportedData[collection][doc.id] = doc.data())) .catch(console.error); const data = JSON.stringify(exportedData); res.setHeader('Content-disposition', 'attachment; filename=fire-export.json'); res.setHeader('Content-type', 'application/json'); res.write(data, function () { res.end(); }); })
Once you have the file fire-export.json downloaded, put it inside the functions folder. Then open the URL for the import function (locally) http://localhost:5001/<project-id>/us-central1/importFirestore. Make sure the collection variable is the same in the export and import.
export const importFirestore = functions.https.onRequest(async (req, res) => { const fs = require("fs"); const collection = "fl_content"; const fileName = "fire-export.json"; const exportedData: any = {}; exportedData[collection] = {}; fs.readFile(fileName, "utf8", async (err: any, data: any) => { if (err) { res.send(err); functions.logger.error(err) return; } const arr = JSON.parse(data); const batch = admin.firestore().batch(); for (const i in arr) { for (const doc in arr[i]) { if (arr[i].hasOwnProperty(doc)) { const ref = admin.firestore().collection(collection).doc(doc); batch.set(ref, arr[i][doc]); } else { functions.logger.error("Missing:", JSON.stringify(doc, null, 2)); } } } await batch .commit() .then(() => console.log("Import to Firestore Complete")) .catch(console.error); res.send("Import to Firestore Complete"); }); });