Help us understand the problem. What is going on with this article?

GASとスプレッドシートでFirestoreにドキュメントID指定でデータを流し込む関数を作る

はじめに

この記事は下記の記事を参考(ほぼコピペ)に書いたコードから
ドキュメントIDを指定してデータを流し込もむコードに修正するコードを書くだけの記事です。

基本的なやり方は下記を御覧ください。
Firestoreのテストデータ投入をGASで楽にする

ドキュメントID指定

下記のコードは Firestoreのテストデータ投入をGASで楽にする を参考に下準備が完了している前提でコードを書いていきます。

要点

  1. スプレッドシートにdocIdという項目を他のフィールドと同様に指定する(型はstringでいい)
  2. var docId = data.docId || ''で指定がアレば変数に入れる
  3. if(docId != '') {}の中でdocIdが指定されている場合の処理を書く
  4. フィールドにdocIdが不要であれば削除するdelete data.docId
  5. {コレクション名}/{ドキュメントID}になる変数を作りfirestore.createDocument();の第一引数に入れる

ソースコード

// カラム名定義
var FIELD_ROW_START = 1;
var FIELD_COL_START = 1;
// 型
var FIELD_TYPE_ROW = 2;
// データの開始行・列
var DATA_ROW_START = 3;
var DATA_COL_START = 1;

// フィールド情報key
var KEY_I_NAME = 'implName'; //実装名
var KEY_TYPE = 'type'; // 型

// 対象シート
var SHEET = "Users";

function myFunction() {
  // firestore接続情報
  var email = "(dlしたJSONにあるclient_emailの値)";
  var key = "(dlしたJSONにあるprivate_keyの値。-----BEGIN PRIVATE KEY-~END PRIVATE KEY-----\nまで全部入れます)";
  var projectId = "(dlしたJSONにあるproject_idの値)";

  // 対象シート
  var sheet = getSheet(SHEET);
  // コレクション名=シート名とする
  var collectionName = sheet.getName();

  // 入力データ領域でループ
  var rowEnd = sheet.getDataRange().getLastRow();

  for(var i = 0; i <= rowEnd - DATA_ROW_START; i++) {
    // 一行ずつ読み込み&登録
    var data =  buildOneRecord(sheet, i);
    // docIdが無ければ自動生成
    var docId = data.docId || '';

    var firestore = FirestoreApp.getFirestore(email, key, projectId);
    var path="";
    if(docId != '') {
      // docId指定の時は「コレクション/{docId}」になるようにする
      path = "/" + docId;
      // フィールドにdocIdが不要であれば連想配列から削除する
      delete data.docId
    }
    // 1レコード登録
    firestore.createDocument(collectionName + path, data);
  }
}

/**
* 1レコードの読み込み
* sheet : 対象シート
* dataNumber: 取り込みデータの行インクリメント数
*/
function buildOneRecord(sheet, dataNumber) {

  // データ領域の最終列
  var colEnd = sheet.getDataRange().getLastColumn();

  var ret = {};
  //フィールド情報を取得しておく
  var fields = getFieldsInfo(sheet);
  Logger.log(dataNumber);
  //一括で読み込み
  var rec = sheet.getSheetValues(DATA_ROW_START + dataNumber, DATA_COL_START, 1, colEnd - DATA_COL_START + 1);
  Logger.log(rec);
  var r = {}
  for(var i = 0; i < fields.length; i++){
    var field = fields[i];
    if(field[KEY_TYPE] == 'array') { 
      // TODO:配列の時
      // 
    } else if(field[KEY_TYPE] == 'map') {
      // TODO:mapの時
      //
    } else if(rec[0][i] && rec[0][i] != '') {
      // その他の場合は値があるもののみ格納する 
      r[field[KEY_I_NAME]] = rec[0][i];;
    }
  }
  return r;
}

/**
* フィールド情報を取得する
* @sheet: シート
*/
function getFieldsInfo(sheet) {
  var colEnd = sheet.getDataRange().getLastColumn();
  var fields = sheet.getSheetValues(FIELD_ROW_START, FIELD_COL_START, FIELD_TYPE_ROW - FIELD_ROW_START + 1, colEnd);

  var f = [];
  for(var i = 0; i < fields[0].length; i++) {
    var logicalName = null;
    var implName = null;
    var type = null;

    if(fields[0][i] != '') {
      // フィールド名
      fieldName = fields[0][i];
      // 型
      fieldType = fields[1][i];

      // 戻り値用値の整形
      var m = {}
      m[KEY_I_NAME] = fieldName;
      m[KEY_TYPE] = fieldType;
      f.push(m);
    }
  }
  return f;
}

/**
* 処理対象のシートを取得する
* @sheetName: 対象シート名
*/
function getSheet(sheetName) {
  if(getSheet.sheet) { return getSheet.sheet; }
  getSheet.sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName); 
  return getSheet.sheet;
}
HorikawaTokiya
歴史とアメコミと筋肉が好き!
FUNEE
based in Japan. manage Fashion & Technology business.
https://www.funee.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away