【问题标题】:How to divide a batch into multiple batches to set documents in Firestore from Android如何将一个批次分成多个批次以在 Android 的 Firestore 中设置文档
【发布时间】:2019-08-11 17:32:50
【问题描述】:

我正在 Android 和 Firestore 上制作应用程序。当我尝试使用 batch 将信息上传到 Firestore 时,我收到以下消息:

com.google.firebase.firestore.FirebaseFirestoreException: INVALID_ARGUMENT:每个请求最多允许 500 次写入

我了解这是对每个人的标准限制(参见Usage and limits),但是如何将批次分成多个批次以避免此问题?

WriteBatch batch = mFirestore.batch();

batch.set(personRef, personData); // This is done 1 time
batch.set(productRef, myProduct, SetOptions.merge()); // This is done multiple times
batch.set(inventoryRef, inventoryData); // This is done multiple times
batch.set(clientRef, clientData); // This is done multiple times

batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "Batch successfully completed!");
                } else {
                    Log.d(TAG, "Error batch: ", task.getException());
                }
            }
        });

我已经搜索了有关它的信息,但是,我只找到了使用 async / task 的 Web 解决方案,对 Android 没有任何帮助。

我试过这个,但是没有运气:

WriteBatch batch = mFirestore.batch(); 
int operationCounter = 0;

// This is just 1 time
DocumentReference personRef = mFirestore.collection..................
batch.set(personRef, personData);

// Multiple times
for (Product product : myProductList) { 
    DocumentReference productRef = mFirestore.collection...............
    batch.set(productRef, product, SetOptions.merge());
    operationCounter++;
    if (operationCounter == 500) { 
       batch.commit();
       // Start a new one
       batch = mFirestore.batch();
       // Reset counter
       operationCounter = 0; 
}

// This is just 1 time
DocumentReference inventoryRef = mFirestore.collection..................
batch.set(inventoryRef, inventory);

我的目标是能够生成多个批次以避免上述错误,并能够一个接一个地执行它们。

【问题讨论】:

  • 使用计数器变量并在每次向批处理添加写入时递增其值。每次递增时,检查计数器是否为 500。发生这种情况时,提交当前批次并开始一个新批次,从上次中断的地方继续。
  • @DougStevenson 从批处理的onComplete 方法开始一个新的?问题是,commit 是在另一个线程中完成的,所以,commit 之后的所有代码都将被执行,我不知道如何等到第一个 commit 完成才能继续下一个commit。在我为 Web 找到的示例中,他们使用 async/task 来执行此操作,但我们在 Android 中没有。
  • 您将获得一个任务,您可以在其中附加回调(如您现在所展示的)。用它从你离开的地方继续。您将无法在一个简单的循环中完成此操作。
  • 对你有帮助的答案意味着在前一个完成时进行操作?
  • @AlexMamo 嗨,不是真的。不需要上一批的答案。如果这就是你的意思。

标签: android firebase google-cloud-firestore


【解决方案1】:

其实你可以做到,方式如下:

const BATCH_SIZE = 5;

let batch = db.batch();
let j = 0;

for (let i = 0; i < products.length; i++) {
  // Do here the stuff you need

  // Add the stuff you have done to the batch
  const ref = db.collection(collection).doc(document);
  batch.set(ref, data);

  // Push the data
  if (j === BATCH_SIZE) {
    await batch.commit();
    batch = db.batch();
    j = 0; // Reset
  } else j++;

}

// Push the remaining data into Firestore
await batch.commit();

请记住,剩余数据将小于BATCH_SIZE(在本例中为 5)。常量BATCH_SIZE 表示批处理中数据的大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多