Firestore 500的批量写入问题

时间:2020-04-08 14:28:55

标签: firebase google-cloud-firestore

我允许导入数据,这使我可以在Firestore中写入大量文档。我保留文件计数器,因此必须减慢写入速度。

// process 75 contacts every 1200ms
return new Promise<boolean>(async (resolve, reject) => {
      timer(0, 1200)
        .pipe(
          takeWhile((_) => !!contacts.length),
        )
        .subscribe(async () => {
          const next = contacts.splice(0, 75);
          await updateContacts(userId, next);
        });
    });

更新联系人的过程如下:-

// It updates three documents: Basic, Extended and the User doc
// which has the count
export async function updateContacts(userId: string, contacts: Contact[]) {
  const firestore = admin.firestore();
  const batch = firestore.batch();
  const userRef = getUserRef(userId);

  for (const contact of contacts) {
    const basicRef = getBasicContactRef(userId);
    const extendedRef = getDetailContactRef(userId, basicRef.id);

    const basic = contact.getBasic();
    batch.set(basicRef, {
      ...basic,
      ...{ timestamp: FieldValue.serverTimestamp() },
    });

    const extended = contact.getExtended();
    batch.set(extendedRef, {
      ...extended,
      ...{ timestamp: FieldValue.serverTimestamp() },
    });

  }

  // Now update the count
  batch.update(userRef, {
    numberOfContacts: FieldValue.increment(contacts.length),
  });

  // commit it all
  return batch.commit();
}

但是,当我使用大量联系人运行它时,它失败并显示以下内容:-

错误:3 INVALID_ARGUMENT:每个请求最多允许500次写入

我认为每个请求的写入次数少于500!

我真的想弄清楚我的头。我不太聪明,所以问你明智的人。知道我在做什么错吗?

1 个答案:

答案 0 :(得分:2)

我有一个预感,问题是您的代码将应用于字段的字段转换。限制500是基于 mutations 的数量,而不是顶级文档操作。我查看了将批处理更新/设置操作转换为突变的内部代码,并且在某些情况下存在倍增因素:

https://github.com/firebase/firebase-js-sdk/blob/9bc4167d5895099ff60fd75d462cbb0d9fd8429e/packages/firestore/src/api/user_data_reader.ts#L101

所以您可能看到的是您的75个批次为batch.set(basicRef)生成了至少2个突变,为batch.set(extendedRef)产生了另外2个突变,等等。我可能还有一些其他隐性成本尚未找到使整体突变数增加到500以上的方法。

您是否可以减少传递给updateContacts()的文档(联系人)数量?