如何将CSV或JSON导入firebase云端防火墙

Ted*_*Ted 45 firebase google-cloud-firestore

有没有办法像firebase实时数据库一样将CSV或JSON导入firebase云防火墙?

在此输入图像描述

Mac*_*uta 52

一般解决方案

我发现许多脚本允许上传一个JSON,但没有一个允许子集合.我上面的脚本处理任何级别的嵌套和子集合.它还处理文档具有自己的数据和子集合的情况.这是基于集合是对象的数组/对象(包括空对象或数组)的假设.

要运行该脚本,请确保已安装npm和node.然后运行您的代码node <name of the file>.请注意,无需将其部署为云功能.

const admin = require('../functions/node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://<your-database-name>.firebaseio.com"
});

const data = require("./fakedb.json");

/**
 * Data is a collection if
 *  - it has a odd depth
 *  - contains only objects or contains no objects.
 */
function isCollection(data, path, depth) {
  if (
    typeof data != 'object' ||
    data == null ||
    data.length === 0 ||
    isEmpty(data)
  ) {
    return false;
  }

  for (const key in data) {
    if (typeof data[key] != 'object' || data[key] == null) {
      // If there is at least one non-object item in the data then it cannot be collection.
      return false;
    }
  }

  return true;
}

// Checks if object is empty.
function isEmpty(obj) {
  for(const key in obj) {
    if(obj.hasOwnProperty(key)) {
      return false;
    }
  }
  return true;
}

async function upload(data, path) {
  return await admin.firestore()
    .doc(path.join('/'))
    .set(data)
    .then(() => console.log(`Document ${path.join('/')} uploaded.`))
    .catch(() => console.error(`Could not write document ${path.join('/')}.`));
}

/**
 *
 */
async function resolve(data, path = []) {
  if (path.length > 0 && path.length % 2 == 0) {
    // Document's length of path is always even, however, one of keys can actually be a collection.

    // Copy an object.
    const documentData = Object.assign({}, data);

    for (const key in data) {
      // Resolve each collection and remove it from document data.
      if (isCollection(data[key], [...path, key])) {
        // Remove a collection from the document data.
        delete documentData[key];
        // Resolve a colleciton.
        resolve(data[key], [...path, key]);
      }
    }

    // If document is empty then it means it only consisted of collections.
    if (!isEmpty(documentData)) {
      // Upload a document free of collections.
      await upload(documentData, path);
    }
  } else {
    // Collection's length of is always odd.
    for (const key in data) {
      // Resolve each collection.
      await resolve(data[key], [...path, key]);
    }
  }
}

resolve(data);
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说很有用,这是一个比Mikki更好(强大和通用)的解决方案.使用这个 - 设置是相同的btw所以你很容易尝试这一个或Mikki的一个 - 只需替换实际的代码. (2认同)
  • 很乐意提供帮助.我在答案中添加了一条注释,以供进一步参考. (2认同)
  • 如果您还可以提供一个JSON结构示例以用于馈入数据库,那就太好了。我运行了脚本,它为每个数据块创建了一个单独的集合,并且字段中的每个字符都作为一个单独的字段出现。现在我要清理一大堆东西,没有批量删除功能... (2认同)
  • 这是子集合的示例:{ "testCollection": { "testDocument": { "testNestedCollection": { "testNestedDocument": { "nestedName": "Jack" } }, "name": "John" } } }。在使用脚本之前,您应该使用 JSON linter,例如 https://jsonlint.com,以确保您的语法正确。 (2认同)

Mik*_*kki 16

您需要一个自定义脚本来执行此操作.

我根据Firebase管理SDK编写了一个,只要firebase库不允许您导入嵌套的数据数组.

const admin = require('./node_modules/firebase-admin');
const serviceAccount = require("./service-key.json");

const data = require("./data.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://YOUR_DB.firebaseio.com"
});

data && Object.keys(data).forEach(key => {
    const nestedContent = data[key];

    if (typeof nestedContent === "object") {
        Object.keys(nestedContent).forEach(docTitle => {
            admin.firestore()
                .collection(key)
                .doc(docTitle)
                .set(nestedContent[docTitle])
                .then((res) => {
                    console.log("Document successfully written!");
                })
                .catch((error) => {
                    console.error("Error writing document: ", error);
                });
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

更新:我写了一篇关于这个主题的文章 - 用数据填充Firestore


Dan*_*ath 8

没有,你需要在这个时候编写自己的脚本.

  • 我喜欢Firebase如何在stackoverflow上竭尽全力以查看开发人员的需求,但是如果这些努力最终导致添加功能,那将是很棒的。我想说JSON / CSV上载将是巨大的:) (2认同)

Dal*_*yen 6

以供参考。我编写了一个有助于在Firestore中导入和导出数据的函数。

https://github.com/dalenguyen/firestore-import-export

  • 伙计,这里的其他解决方案被低估了。谢谢!! (2认同)

pas*_*asx 6

我使用了Maciej Caputa提供的通用解决方案.谢谢 (:

这里有一些提示.假设您在该解决方案的functions文件夹中安装了所需的Firebase节点模块的Ionic Firebase应用程序.这是标准的Ionic Firebase安装.我创建了一个导入文件夹来保存同一级别的脚本和数据.

文件夹层次结构

myIonicApp
    functions
        node_modules
            firebase-admin
ImportFolder
    script.js
    FirebaseIonicTest-a1b2c3d4e5.json
    fileToImport.json
Run Code Online (Sandbox Code Playgroud)

脚本参数

const admin = require('../myIonicApp/functions/node_modules/firebase-admin'); //path to firebase-admin module
const serviceAccount = require("./FirebaseTest-xxxxxxxxxx.json"); //service account key file

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://fir-test-xxxxxx.firebaseio.com" //Your domain from the hosting tab
});
Run Code Online (Sandbox Code Playgroud)

创建服务帐户密钥文件

  • 在项目的Firebase控制台中,在"项目覆盖"项旁边,单击齿轮图标,然后选择"用户和权限"
  • 在屏幕底部,单击"高级权限设置"

访问Google Cloud Platform Console

  • 这将打开Goog​​le Cloud Platform Console的另一个标签
  • 在左侧选择"服务帐户"项
  • 为现有服务帐户创建服务帐户

我只是在App Engine默认服务帐户中添加了一个密钥

Create key函数将提供将密钥下载到JSON文件

创建服务帐户密钥

JSON数据结构

要使用提供的脚本,数据结构必须如下:

{
  "myCollection" : {
    "UniqueKey1" : {
      "field1" : "foo",
      "field2" : "bar"
    },{
    "UniqueKey2" : {
      "field1" : "fog",
      "field2" : "buzz"
    }...
}
Run Code Online (Sandbox Code Playgroud)