LoginSignup
0
1

More than 3 years have passed since last update.

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

Posted at

はじめに

この記事は下記の記事を参考(ほぼコピペ)に書いたコードから
ドキュメント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;
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1