将Excel / Google表格电子表格导入Cloud Firestore数据库的最简单方法是什么?

时间:2019-05-08 03:55:21

标签: google-cloud-firestore

我需要一次将大数据表导​​入数据库。我目前将其保存为Excel文件,但很高兴将其复制到Google表格等中。

到目前为止,我已经直接通过Cloud Firestore手动添加了一些条目。

是否已经有解决方案来实现这一目标?

1 个答案:

答案 0 :(得分:1)

我认为将表数据导出到Firestore的最简单方法是使用Google Apps脚本库(用于Google表格)。

步骤1

复制作为示例创建的THIS example Google Spreadsheet

步骤2

从步骤1的示例Google电子表格副本的菜单中,单击Tools > Script Editor。这应该打开与示例电子表格相关联的示例Google App脚本。

步骤3

遵循安装this library的步骤,然后使用以下内容更新脚本:

  • 电子邮件
  • projectID

这些变量是通过转到Google Service Accounts page生成的。这将要求您已经具有Firebase或Google Cloud帐户设置。我不会重复aforementioned Github writeup中已经迭代的所有步骤。只需仔细地跟随它们,并认识到private_key是从-----BEGIN PRIVATE KEY-----\n开始,其间的一切并以\n-----END PRIVATE KEY-----\n结束的全部密钥

步骤4

在电子表格中插入包含数据的页面,然后编辑脚本以使用新的工作表名称和数据。我已经对脚本进行了评论,因此很清楚几乎每一行代码都在做什么。对于只想浏览此spreadsheet背后的Google App脚本的人,以下是代码:

// Note this Script uses an external library as per this page: 
// https://github.com/grahamearley/FirestoreGoogleAppsScript
// This solution requires a Google Spreadhseet and a Firebase Account
// FOLLOW THE INSTRUCTIONS ON THAT GITHUB REPO TO SETUP NEEDED API KEYS!!!

//Global Variables
const ss = SpreadsheetApp.getActiveSpreadsheet(); // Gets the active "workbook"
const sheet = ss.getSheetByName('Restaurants'); // CHANGE TO YOUR SHEET NAME
const headerRowNumber = 1; // If you have more than one row for your header, then change this value to number of header rows

// If you want to mark modified cells, then set up a trigger for the following function:
// Edit > Current Project Triggers > (+ Add Trigger) > On Edit Spreadsheet etc
function onEdit(e) {
  var cell = ss.getActiveCell(); //This will also effectively get our row
  var dataRange = sheet.getDataRange(); //This checks for all rows/columns with data
  var modifiedCol = dataRange.getLastColumn()-1; //Our "modified" column should be the second to last
  if (cell.getColumn() < modifiedCol && cell.getRow() > headerRowNumber) { //If we edit any cells to the left of our modified column and below our header...
    var celltoMark = sheet.getRange(cell.getRowIndex(),modifiedCol)   //Get the R/C cordinates of cell to place modified time
    celltoMark.setValue(new Date()); //write timestamp to that cell
  }
};
// This will parse any comma separated lists you create in any of your fields (useful for search words, or attributes, etc)
function listToArray(list) {
  var ogArray = list.split(","); //Input is a comma separated list
  let trimmedArr = ogArray.map(string => string.trim()); //Let's strip out the leading/trailing whitespaces if any
  return trimmedArr; //return the cleaned array
}

function writeToFireStore() {
  const email = 'sheets@yourprojectid.iam.gserviceaccount.com'; // CHANGE THIS!!!
  const key = '-----BEGIN PRIVATE KEY-----\nYOURPRIVATEKEY\n-----END PRIVATE KEY-----\n'; // CHANGE THIS!!!
  const projectID = 'yourprojectid'; // CHANGE THIS!!!
  var firestore = FirestoreApp.getFirestore(email, key, projectID);
  const collection = "MySpreadsheetData"; // Name of your Firestore Database "Collection"

  var dataRange = sheet.getDataRange().offset(headerRowNumber, 0, sheet.getLastRow() - headerRowNumber); //this is your data range
  var data = dataRange.getValues(); // this is an array of your datarange's values
  var lastCol = dataRange.getLastColumn(); // this is the last column with a header
  var newDoc = {}; // Instantiate your data object. Each one will become the data for your firestore documents

  // r = row number in this case
  for (let r = 0; r <= dataRange.getLastRow(); r++) {
    //Logger.log("R = ",r);
    var cellMod = dataRange.getCell(r+1, lastCol-1);
    var cellFS = dataRange.getCell(r+1, lastCol);
    var cellModVal = cellMod.getValue();
    var cellFSVal = cellFS.getValue();
    //
    // IMPORTANT READ THIS IMPORTANT READ THIS IMPORTANT READ THIS IMPORTANT READ THIS IMPORTANT READ THIS!!!
    // Well, read the line below...
    if (r > 2) break; //Comment Out this line after you're done testing otherwise you'll write all your rows to firestore after every run
    newDoc[r] = {
      name : data[r][1],
      category : data[r][2],
      cuisine : data[r][3],
      address: {
        add1: data[r][4],
        add2: data[r][5],
        city: data[r][6],
        state: data[r][7],
        zip: data[r][8]
      },
      tel: data[r][9],
      searchterms: listToArray(data[r][10]) //Let's turn a csv list into an array
    }

    // For the sake of efficiency and to save $, we WON'T create documents that have already been created...
    // ...and we won't update documents that have a fireStore Timestamp that's newer than a Modified Timestamp

      // If there's not firestore timestamp in our spreadsheet, then let's create firestore document and update firestore stamp:
    if (!cellFSVal) {
      var now = new Date(); //Generate timestamp right now
      try {
        firestore.createDocument(collection + "/" + data[r][0], newDoc[r]); // To Use Your Own Document ID
        //Now let's insert a timestamp in our Firestore TS column of the sheet so we know it's been added to Firestore
        cellFS.setValue(now);
        Logger.log("Row ",r,"(",data[r][1],") is NEW and was added to FireStore Successfully");
      } catch (e) {
        Logger.log("Error: ",e," : Document with same name already existed in Firestore."); 
      }
    }
    //var if FS Timestamp exists but, the modified time stamp is greater, let's update the Firstore Document
    else if ((cellFSVal) && (cellModVal > cellFSVal)) {
      try {
        firestore.updateDocument(collection + "/" + data[r][0], newDoc[r]);
        //Now let's insert a timestamp in our Firestore TS column of the sheet so we know it's been updated to Firestore
        cellFS.setValue(now);
        Logger.log("Row ",r,"(",data[r][1],") updated/edited.");
      } catch (e) {
        Logger.log("Error: ",e," : Document existed, we tried updating it, but jack shit happened.");
      }
    }
    else {
      Logger.log("Row ",r,"(",data[r][1],") Already in Firestore & hasn't been modified. Skipped.");
    }
  }
}

步骤5

根据您的需要修改脚本后,就该运行脚本了。只需保存(File > Save,然后从菜单栏中的“ 选择功能”下拉选择器中选择功能“ writeToFireStore ”(位于错误和灯泡),然后点击“播放”图标(位于错误图标的左侧)。此时,可能会提示您接受运行脚本的权限(如果要运行脚本,则需要接受该权限)。接受权限后,如果尚未运行,请再次运行“ writeToFireStore”功能,瞧!

注意:

我创建了一个函数,该函数自动将Modified Timestamp写入目标表的倒数第二列,并且在您运行该函数时,编写一个Firestore时间戳(这样您就可以知道哪些行已成功导出到Firestore)。这样,如果您再次运行firestore函数,并且没有更改工作表上的数据,它将不会费心用相同的数据更新数据库(这将节省金钱和/或服务器资源)。为了使用此功能,您必须设置项目触发器(在脚本的注释中对其进行了解释)。