[英]How to import test data into Firebase Firestore emulator from production for easy testing?
I am building a firebase function that listens to a trigger and sends a push notification to users.我正在构建一个 firebase function 来监听触发器并向用户发送推送通知。 The trigger is based on firestore data that's too complex for me to manually re-recreate every time on firestore emulator.触发器基于对我来说太复杂的 firestore 数据,无法每次在 firestore 模拟器上手动重新创建。
I tried emulating functions, but hooking up to firestore production, but seems like in this case, trigger functions don't work我尝试模拟功能,但连接到 Firestore 生产,但似乎在这种情况下,触发功能不起作用
What I want to do is export my data from my production Firestore then import it into my emulator firestore, so that at least, the copy I am working with is closely mimicking what I have on prod;我想要做的是从我的生产 Firestore 中导出我的数据,然后将其导入到我的模拟器 Firestore 中,这样至少,我正在使用的副本非常模仿我在 prod 上的内容; to be clear, the data is small, so I am not worried about downloading terabytes of data.需要明确的是,数据很小,所以我不担心下载 TB 的数据。
I found a way of importing data into an emulator , but not sure if this would work with production data or how I would dump the data from production.我找到了一种将数据导入模拟器的方法,但不确定这是否适用于生产数据或如何从生产中转储数据。
firebase emulators:start --import=./some-directory
You can manually export from Production and then import into the Firestore emulator.您可以从 Production 手动导出,然后导入 Firestore 模拟器。
Start by doing an export of your production data to a file.首先将生产数据导出到文件。 In the example, I export just the "users" collection within an onRequest function so I can kick-off by calling the URL.在示例中,我仅导出 onRequest function 中的“用户”集合,因此我可以通过调用 URL 来启动。 Note, this this function will not handle subcollections.注意,这个 function 不会处理子集合。
exports.exportFirestore = functions.https.onRequest(async (req, res) => {
const fs = require("fs");
const collection = "users";
const fileName = "fs-export.json";
const exportedData = {};
exportedData[collection] = {};
await admin
.firestore()
.collection(collection)
.get()
.then((snapshot) => {
return snapshot.forEach((doc) => {
exportedData[collection][doc.id] = doc.data();
});
})
.catch(console.error);
fs.writeFile(fileName, JSON.stringify(exportedData), (err) => {
if (err) {
console.log(err);
} else {
console.log("Firestore Export Complete.");
res.send("Firestore Export Complete.");
}
});
});
Next, import the file into the local Firestore emulator.接下来,将文件导入本地 Firestore 模拟器。 Very important: be sure to have the Firestore emulator running otherwise you'll be importing your data back to prod.非常重要:确保运行 Firestore 模拟器,否则您会将数据导入回产品。 Be sure to check that Firestore is running by checking the web UI: http://localhost:4000 .请务必通过检查 web UI: http://localhost:4000来检查 Firestore 是否正在运行。 Start the emulator with: firebase emulators:start
使用以下命令启动仿真器: firebase emulators:start
exports.importFirestore = functions.https.onRequest(async (req, res) => {
const fs = require("fs");
let collection;
const fileName = "fs-export.json";
const exportedData = {};
exportedData[collection] = {};
fs.readFile(fileName, "utf8", async (err, data) => {
if (err) {
return console.log(err);
}
const arr = JSON.parse(data);
const batch = admin.firestore().batch();
for (let i in arr) {
collection = i;
for (let doc in arr[i]) {
if (arr[i].hasOwnProperty(doc)) {
const ref = admin.firestore().collection(collection).doc(doc);
batch.set(ref, arr[i][doc]);
} else {
console.log("Missing:", JSON.stringify(doc, null, 2));
}
}
}
await batch
.commit()
.then(() => {
return console.log("Import to Firestore Complete");
})
.catch(console.error);
return res.send("Import to Firestore Complete");
});
});
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.我的回答深受@Geoffrey Bourne 回答的启发,但我必须修改一些内容并找出更多细节才能使其正常工作。
First, I upload the exportFirestore
to Cloud Functions (production).首先,我将exportFirestore
上传到 Cloud Functions(生产)。 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
当我通过这个 URL https://us-central1-<project-id>.cloudfunctions.net/exportFirestore
运行它时,我下载了一个文件,因为 Cloud Functions 是read-only
The below code is for one collection named fl_content
, I'll consider expanding it to multiple collections下面的代码是一个名为fl_content
的集合,我会考虑将它扩展到多个 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.下载文件fire-export.json
,将其放在functions
文件夹中。 Then open the URL for the import function (locally) http://localhost:5001/<project-id>/us-central1/importFirestore
.然后打开 URL 用于导入 function(本地) http://localhost:5001/<project-id>/us-central1/importFirestore
。 Make sure the collection
variable is the same in the export and import.确保导出和导入中的collection
变量相同。
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");
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.