在 Firestore 中通过 docId 批量设置文档字段时遇到问题

Posted

技术标签:

【中文标题】在 Firestore 中通过 docId 批量设置文档字段时遇到问题【英文标题】:Trouble batch setting a document field by docId in Firestore 【发布时间】:2022-01-22 09:00:06 【问题描述】:

我使用 firebase (firestore) 已经有一段时间了,但我有点卡住了,想知道是否有人能想到解决方案。

在 Firestore 数据库中,我有一个用户集合,每个用户都有一个电子邮件地址和几个其他字段。在这种情况下,我正在检查用户电子邮件是否存在,如果存在,我想为具有 listUid 的特定用户创建一个列表字段。我通过电子邮件引用用户,获取这些用户的 docId,然后尝试为每个用户设置一个列表字段。

我没有从 firestore 收到任何错误,它只是由于某种原因没有在数据库中更新,我不知道我哪里出错了。提前致谢

export const addListUidToExistingUserList = (
   firestore ,
  emailArray,
  listUid
) => 
  return async () => 
    let docIds = [];

    emailArray.forEach((emailAddress) => 
      //find users by email (works)
      const query = db
        .collection("users")
        .where("email", "==", emailAddress);

      //get docId's for user with matching email (works)
      query.get().then((querySnapshot) => 
        querySnapshot.forEach((doc) => 
          docIds.push(doc.id);
        );
      );

      //add a new list with corresponding listUid (does not work)
      docIds.forEach((id) => 
        let userRef = db.collection("users").doc(id);
        batch.set(userRef,  lists: [ listUid ] );
      );
    );
    return await batch.commit();
  ;
;

【问题讨论】:

【参考方案1】:

您遇到此问题是因为您的 docIds 数组在您调用 docIds.forEach 时始终为空。

这是因为query.get().then 异步运行,所以docIds.forEach 没有等待它完成。

你可以:

await query.get().then;或 在query.getthen 回调中添加docIds.forEach 函数。

以下是您可能的修复方法:

    await query.get().then
//get docId's for user with matching email (works)
await query.get().then((querySnapshot) => 
  querySnapshot.forEach((doc) => 
    docIds.push(doc.id);
  );
);

或者:

    docIds.forEachthen
//get docId's for user with matching email (works)
query.get().then((querySnapshot) => 
  querySnapshot.forEach((doc) => 
    docIds.push(doc.id);
  );

  docIds.forEach((id) => 
    let userRef = db.collection("users").doc(id);
    batch.set(userRef,  lists: [ listUid ] );
  );
);

注意:当然,您也可以将batch.set 直接添加到querySnapshot.docs.forEach 的第一次迭代中,以防止不必要的迭代。

【讨论】:

感谢您的帮助,这是有道理的,但现在我收到了 A write batch can no longer be used after commit() has been called. 知道为什么会这样吗? 我实际上已经解决了batch.commit() 的问题。我在函数范围之外调用 db.batch() 。因此,该函数第一次运行时,它会调用 batch.commit() 并提交所有更改。因此,当该函数再次运行时,我们会收到该错误,因为已经为该实例调用了 commit。解决方案是在范围内调用!

以上是关于在 Firestore 中通过 docId 批量设置文档字段时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

在 MySQL 中通过 Connector/J 使用 getGeneratedKeys 和批量插入

如何读取地图中的 Firestore 值?

PHP中通过ZipArchive批量下载pdf文件

在颤动中通过字符串获取数据

currentuser 如何在flutter中通过fcm向另一个用户发送请求通知?

如何在 Flutter (Dart) 中通过新路由获取子级 StreamProvider 数据