How to import CSV or JSON to firebase cloud firest

2019-01-12 18:33发布

Is there a way to import CSV or JSON to firebase cloud firestore like in firebase realtime database?

enter image description here

8条回答
我想做一个坏孩纸
2楼-- · 2019-01-12 18:55

There is not, you'll need to write your own script at this time.

查看更多
手持菜刀,她持情操
3楼-- · 2019-01-12 18:57

I used the General Solution provided by Maciej Caputa. Thank you (:

Here are a few hints. Assuming that you have an Ionic Firebase application installed with the required Firebase node modules in the functions folder inside that solution. This is a standard Ionic Firebase install. I created an import folder to hold the script and data at the same level.

Folder Hierarchy

myIonicApp
    functions
        node_modules
            firebase-admin
ImportFolder
    script.js
    FirebaseIonicTest-a1b2c3d4e5.json
    fileToImport.json

Script Parameters

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
});

Domain name from the Hosting tab

Creating the Service Account Key File

  • In the Firebase console for your project, next to the Project Overwiew item, click on the gear icon and select Users and permissions
  • At the bottom of the screen, click Advanced permission settings

Accessing Google Cloud Platform Console

  • This opens another tab for the Google Cloud Platform Console
  • On the left select the Service Accounts item
  • Create a Service Account for an existing Service Account

I simply added a key to the App Engine default service account

The Create key function will offer to download the key to a JSON file

Creating the Service Account Key

JSON Data Structure

To use the script provided, the data structure must be as follows:

{
  "myCollection" : {
    "UniqueKey1" : {
      "field1" : "foo",
      "field2" : "bar"
    },{
    "UniqueKey2" : {
      "field1" : "fog",
      "field2" : "buzz"
    }...
}
查看更多
祖国的老花朵
4楼-- · 2019-01-12 19:06

For reference. I wrote a function that helps to import and export data in Firestore.

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

查看更多
来,给爷笑一个
5楼-- · 2019-01-12 19:09

General Solution

I've found many takes on a script allowing to upload a JSON but none of them allowed sub-collections. My script above handles any level of nesting and sub-collections. It also handles the case where a document has its own data and sub-collections. This is based on the assumption that collection is array/object of objects (including an empty object or array).

To run the script make sure you have npm and node installed. Then run your code as node <name of the file>. Note, there is no need to deploy it as a cloud funciton.

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 then it 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);
查看更多
趁早两清
6楼-- · 2019-01-12 19:15

You need a custom script to do that.

I wrote one based on the Firebase admin SDK, as long as firebase library does not allow you to import nested arrays of data.

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);
                });
        });
    }
});

Update: I wrote an article on this topic - Filling Firestore with data

查看更多
对你真心纯属浪费
7楼-- · 2019-01-12 19:19

https://gist.github.com/JoeRoddy/1c706b77ca676bfc0983880f6e9aa8c8

This should work for an object of objects (generally how old firebase json is set up). You can add that code to an app that's already configured with Firestore.

Just make sure you have it pointing to the correct JSON file.

Good luck!

查看更多
登录 后发表回答