首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法修改已提交FireStore的WriteBatch

无法修改已提交FireStore的WriteBatch
EN

Stack Overflow用户
提问于 2019-08-09 20:57:17
回答 1查看 1K关注 0票数 2

我试着为大型JSON文件创建一个自定义的导入命令,基于这个命令:https://github.com/codediodeio/firestore-migrator

但是我在我的自定义命令上遇到了以下问题:

代码语言:javascript
复制
(node:19413) UnhandledPromiseRejectionWarning: Error: Cannot modify a WriteBatch that has been committed.
    at WriteBatch.verifyNotCommitted (/Users/mac-clement/Documents/projets/dpas/gcp/import-data/csv-import/node_modules/@google-cloud/firestore/build/src/write-batch.js:116:19)
    at WriteBatch.set (/Users/mac-clement/Documents/projets/dpas/gcp/import-data/csv-import/node_modules/@google-cloud/firestore/build/src/write-batch.js:234:14)
    at Object.<anonymous> (/Users/mac-clement/Documents/projets/dpas/gcp/import-data/csv-import/dist/src/importJson.js:90:17)
    at Generator.next (<anonymous>)
    at /Users/mac-clement/Documents/projets/dpas/gcp/import-data/csv-import/dist/src/importJson.js:7:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/mac-clement/Documents/projets/dpas/gcp/import-data/csv-import/dist/src/importJson.js:3:12)
    at batchSet (/Users/mac-clement/Documents/projets/dpas/gcp/import-data/csv-import/dist/src/importJson.js:85:33)
    at Object.<anonymous> (/Users/mac-clement/Documents/projets/dpas/gcp/import-data/csv-import/dist/src/importJson.js:74:19)
    at Generator.next (<anonymous>)
(node:19413) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 174)

这可能是一个promise问题,因为在batchCommit函数中设置了一个新的批处理...但是我很难找到它!感谢您的帮助!

代码语言:javascript
复制
/**
 * Dependencies
 */
import * as admin from "firebase-admin";
import * as fs from "file-system";
import * as _ from "lodash";
import {streamArray} from "stream-json/streamers/StreamArray";
import {parser} from "stream-json";

/**
 * Global variables
 */
let args;
let db = admin.firestore();
let batch = db.batch();
let batchCount = 0;
let totalSetCount = 0;

/**
 * Main function
 *
 * @param file
 * @param collection
 * @param options
 */
export const execute = (file: string, collection: string, options) => {
  args = options;
  if( args.dryRun ) args.verbose = true;

  console.log('Importing data...');
  console.log('File path: ' + file);
  console.log('Collection: ' + collection);
  console.log('Limit: ' + args.limit);
  console.log('Chunk: ' + args.chunk);

  return fs.createReadStream(file)
    .pipe(parser())
    .pipe(streamArray())
    .on('data', async (row) => {
      await Promise.resolve(manageRow(row.value, collection));
    })
    .on('end', async () => {
      // Final Batch commit and completion message.
      await batchCommit(false);
      console.log(args.dryRun
        ? 'Dry-Run complete, Firestore was not updated.'
        : 'Import success, Firestore updated!'
      );
      console.log(`Total documents written: ${totalSetCount}`);
    });
}

/**
 *
 * @param row
 * @param collection
 */
const manageRow = async (row: object, collection: string) => {
  const colRef = db.collection(collection);

  return new Promise(async (resolve, reject) => {
    for (let [id, item] of Object.entries(row)) {
      const docRef = colRef.doc(id);
      await batchSet(docRef, item);
    }
    resolve();
  });
}

/**
 * Add an item in the batch and call commit if batch size reached chunk
 *
 * @param ref
 * @param item
 */
const batchSet = async (ref: FirebaseFirestore.DocumentReference, item: object) => {
  // Log if requested
  args.verbose && console.log(`Writing: ${ref.path}`);    

  // Set the Document Data
  ++totalSetCount;
  await batch.set(ref, item);

  // Commit batch on chunk size
  if (++batchCount % args.chunk === 0) {
    await batchCommit();
  }
}

/**
 * Commit changes to FireStore database and initialize a new batch if recycle is set to true
 *
 * @param recycle
 */
const batchCommit = async (recycle: boolean = true) => {
  // Nothing to commit or dry run so do not commit
  if (!batchCount || args.dryRun) return;

  // Log if requested
  args.verbose && console.log(batchCount + ' documents have been written so long ...');

  await batch.commit();

  if(recycle) {
    batch = db.batch();
    batchCount = 0;
  }
}
EN

回答 1

Stack Overflow用户

发布于 2019-08-10 02:08:45

看起来您正在尝试重用一个批处理对象来进行多次提交。这是无效的。为每次提交创建一个新的批处理对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57430565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档