如何将测试数据从生产环境导入 Firebase Firestore 模拟器以便于测试?

Zor*_*ayr 6 node.js firebase firebase-tools google-cloud-firestore

我正在构建一个侦听触发器并向用户发送推送通知的 firebase 函数。触发器基于对我来说太复杂的 firestore 数据,我无法每次在 firestore 模拟器上手动重新创建。

我尝试模拟函数,但连接到 firestore 生产,但似乎在这种情况下,触发器函数不起作用

我想要做的是从我的生产 Firestore 导出我的数据,然后将其导入我的模拟器 firestore,这样至少,我正在使用的副本密切模仿我在生产中的数据;需要明确的是,数据很小,所以我不担心下载 TB 级的数据。

我找到了一种将数据导入模拟器的方法,但不确定这是否适用于生产数据或如何从生产中转储数据。

firebase emulators:start --import=./some-directory

Run Code Online (Sandbox Code Playgroud)

G g*_*ffo 8

保留数据的一种方法是在退出时导出到目录并在开始时导入同一目录

firebase emulators:start  --import=./mydir --export-on-exit mydir 
Run Code Online (Sandbox Code Playgroud)


Geo*_*rne 6

您可以手动从 Production 导出,然后导入到 Firestore 模拟器中。

首先将生产数据导出到文件。在示例中,我仅导出 onRequest 函数中的“users”集合,以便我可以通过调用 URL 来启动。注意,这个函数不会处理子集合。

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.");
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

接下来,将该文件导入本地 Firestore 模拟器。非常重要:请务必运行 Firestore 模拟器,否则您会将数据导入回产品。请务必通过检查 Web UI 来检查 Firestore 是否正在运行:http://localhost:4000。使用以下命令启动模拟器: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");
  });
});
Run Code Online (Sandbox Code Playgroud)