【问题标题】:How to Remove Arrays of Element in Firebase Cloud Firestore using Ionic 4如何使用 Ionic 4 删除 Firebase Cloud Firestore 中的元素数组
【发布时间】:2020-03-14 00:13:15
【问题描述】:

In My Cloud Firestore 数据库结构如下所示。现在,我想像这样删除基于Index 0Index 1 的索引位置。

const arrayLikedImagesRef = {imageurl: image, isliked: true};
  const db = firebase.firestore();
  const deleteRef = db.collection('userdata').doc(`${phno}`);
  deleteRef.update({
    likedimages: firebase.firestore.FieldValue.arrayRemove(arrayLikedImagesRef)
  });
});

【问题讨论】:

    标签: firebase firebase-realtime-database google-cloud-firestore ionic4


    【解决方案1】:

    正如explained here,“尝试更新或删除特定索引处的数组元素时可能会发生坏事”。这就是为什么Firestore official documentation 表明arrayRemove() 函数将元素(字符串)作为参数,而不是索引。

    正如this answer 所建议的那样,如果您更喜欢使用索引,那么您应该获取整个文档,获取数组,修改它并将其添加回数据库。

    【讨论】:

      【解决方案2】:

      您不能使用FieldValue 按索引删除数组项。相反,您可以使用 transaction 删除数组项。使用事务可确保您实际上写回了您期望的确切数组,并且可以与其他写入者打交道。

      例如(我这里使用的参考是任意的,当然你需要提供正确的参考):

      db.runTransaction(t => {
        const ref = db.collection('arrayremove').doc('targetdoc');
      
        return t.get(ref).then(doc => {
          const arraydata = doc.data().likedimages;
      
          // It is at this point that you need to decide which index
          // to remove -- to ensure you get the right item.
          const removeThisIndex = 2;
      
          arraydata.splice(removeThisIndex, 1);
          t.update(ref, {likedimages: arraydata});
        });
      });
      

      当然,正如上面代码中所指出的,只有当您实际在事务本身内部时,您才能确定您将要删除正确的索引——否则您获取的数组可能与您最初选择的索引位于。所以要小心!


      也就是说,鉴于FieldValue.arrayRemove 不支持嵌套数组(因此您不能将多个映射传递给它以删除),您可能会问该怎么办。在这种情况下,您只需要实际检查值的上述变体(此示例仅适用于单个值和固定对象类型,但您可以轻松地将其修改为更通用):

      const db = firebase.firestore();
      const imageToRemove = {isliked: true, imageurl: "url1"};
      
      db.runTransaction(t => {
        const ref = db.collection('arrayremove').doc('byvaluedoc');
        return t.get(ref).then(doc => {
          const arraydata = doc.data().likedimages;
          const outputArray = []
          arraydata.forEach(item => {
            if (!(item.isliked == imageToRemove.isliked &&
                  item.imageurl == imageToRemove.imageurl)) {
                 outputArray.push(item);
                }
          });
          t.update(ref, {likedimages: outputArray});
        });
      });
      

      (我确实注意到在您的代码中您使用的是原始布尔值,但数据库将 isliked 项目作为字符串。我测试了上面的代码,尽管如此,它似乎仍然有效,但最好是在使用类型时保持一致)。

      【讨论】:

      • 非常感谢您救了我的命,从过去的一周开始,我正在努力解决这个问题,但我无法感谢您的帮助。
      猜你喜欢
      • 2021-07-24
      • 1970-01-01
      • 2022-06-23
      • 2020-03-27
      • 1970-01-01
      • 2019-02-19
      • 2021-09-11
      • 2018-12-14
      • 1970-01-01
      相关资源
      最近更新 更多