【问题标题】:How to delete document from firestore using where clause如何使用 where 子句从 Firestore 中删除文档
【发布时间】:2018-04-21 03:53:15
【问题描述】:
var jobskill_ref = db.collection('job_skills').where('job_id','==',post.job_id);
jobskill_ref.delete();

抛出错误

jobskill_ref.delete 不是函数

【问题讨论】:

    标签: javascript firebase google-cloud-firestore


    【解决方案1】:

    Kotlin 的代码,包括失败监听器(用于查询和删除每个文档):

    fun deleteJobs(jobId: String) {
        db.collection("jobs").whereEqualTo("job_id", jobId).get()
            .addOnSuccessListener { documentSnapshots ->
                for (documentSnapshot in documentSnapshots)
                    documentSnapshot.reference.delete().addOnFailureListener { e ->
                        Log.e(TAG, "deleteJobs: failed to delete document ${documentSnapshot.reference.id}", e)
                    }
            }.addOnFailureListener { e ->
                Log.e(TAG, "deleteJobs: query failed", e)
            }
    }
    

    【讨论】:

      【解决方案2】:

      或试试这个,但你必须事先有 id

      export const deleteDocument = (id) => {
      return (dispatch) => {
          firebase.firestore()
          .collection("contracts")
          .doc(id)
          .delete()
      }
      

      }

      【讨论】:

        【解决方案3】:

        我解决这个问题的方法是给每个文档一个 uniqueID,在该字段上查询,获取返回文档的 documentID,并在删除中使用它。像这样:

        (斯威夫特)

        func rejectFriendRequest(request: Request) {
            DispatchQueue.global().async {
                self.db.collection("requests")
                    .whereField("uniqueID", isEqualTo: request.uniqueID)
                    .getDocuments { querySnapshot, error in
                        if let e = error {
                            print("There was an error fetching that document: \(e)")
                        } else {
                            self.db.collection("requests")
                                .document(querySnapshot!.documents.first!.documentID)
                                .delete() { err in
                                    if let e = err {
                                        print("There was an error deleting that document: \(e)")
                                    } else {
                                        print("Document successfully deleted!")
                                    }
                                }
                        }
                    }
            }
        }
        

        代码可以稍微清理一下,但这是我想出的解决方案。希望它可以帮助将来的人!

        【讨论】:

          【解决方案4】:
          //The following code will find and delete the document from firestore
          
          const doc = await this.noteRef.where('userId', '==', userId).get();
          doc.forEach(element => {
              element.ref.delete();
              console.log(`deleted: ${element.id}`);
          });
          

          【讨论】:

          • 可以批量删除吗?因为逐个文档删除文档不是最佳选择。
          • 不确定您是否必须尝试。
          • @astroboy 我们如何使用批量删除,请分享。谢谢。
          【解决方案5】:

          您现在可以这样做了:

          db.collection("cities").doc("DC").delete().then(function() {
              console.log("Document successfully deleted!");
          }).catch(function(error) {
              console.error("Error removing document: ", error);
          });
          

          【讨论】:

            【解决方案6】:

            如果您在客户端使用 Cloud Firestore,则可以使用唯一密钥生成器包/模块(如 uuid)来生成 ID。然后,您将文档的 ID 设置为从 uuid 生成的 ID,并将对该 ID 的引用存储在您存储在 Firestore 中的对象上。

            例如: 如果您想将人员对象保存到 Firestore,首先,您将使用 uuid 为人员生成 ID,然后按如下所示进行保存。

            const uuid = require('uuid') 
            
            const person = { name: "Adebola Adeniran", age: 19}
            const id = uuid() //generates a unique random ID of type string
            const personObjWithId = {person, id} 
            
            export const sendToFireStore = async (person) => {
              await db.collection("people").doc(id).set(personObjWithId);
            };
            
            // To delete, get the ID you've stored with the object and call // the following firestore query
            
            export const deleteFromFireStore = async (id) => {
              await db.collection("people").doc(id).delete();
            };
            

            希望这可以帮助任何在客户端使用 firestore 的人。

            【讨论】:

            • 我认为这并不能真正解决所提出的问题。此外,Firebase 会为您自动生成文档 ID,因此无需导入额外的模块/包来单独处理。
            【解决方案7】:
            delete(seccion: string, subseccion: string) 
            {
             const deletlist = this.db.collection('seccionesclass', ref => ref.where('seccion', '==', seccion).where('subseccion', '==' , subseccion))
            deletlist.get().subscribe(delitems => delitems.forEach( doc=> doc.ref.delete()));
                alert('record erased');
            }
            

            【讨论】:

            • 本网站上通常不赞成仅使用代码的答案。您能否编辑您的答案以包含一些 cmets 或对您的代码的解释?解释应回答以下问题:它有什么作用?它是如何做到的?它去哪儿了?它如何解决OP的问题?见:How to anwser。谢谢!
            【解决方案8】:

            我为此使用batched writes。例如:

            var jobskill_ref = db.collection('job_skills').where('job_id','==',post.job_id);
            let batch = firestore.batch();
            
            jobskill_ref
              .get()
              .then(snapshot => {
                snapshot.docs.forEach(doc => {
                  batch.delete(doc.ref);
                });
                return batch.commit();
              })
            

            ES6 异步/等待:

            const jobskills = await store
              .collection('job_skills')
              .where('job_id', '==', post.job_id)
              .get();
            
            const batch = store.batch();
            
            jobskills.forEach(doc => {
              batch.delete(doc.ref);
            });
            
            await batch.commit();
            

            【讨论】:

            • 请注意A batched write can contain up to 500 operations,因此可能需要额外的逻辑,具体取决于文档的数量
            • 没有运行循环,我们如何执行这个解决方案?请建议。谢谢。
            【解决方案9】:

            当然,你也可以使用 await/async:

            exports.delete = functions.https.onRequest(async (req, res) => {
            try {
                var jobskill_ref = db.collection('job_skills').where('job_id','==',post.job_id).get();
                jobskill_ref.forEach((doc) => {
                  doc.ref.delete();
                });
              } catch (error) {
                return res.json({
                  status: 'error', msg: 'Error while deleting', data: error,
                });
              }
            });
            

            我不知道为什么你必须get()它们并循环它们,然后delete()它们,而你可以像任何 SQL 语句一样准备一个查询,其中包含一步删除的位置,但 Google 决定这样做。所以,目前,这是唯一的选择。

            【讨论】:

            • 没有运行循环,我们如何执行这个解决方案?请建议。谢谢。
            【解决方案10】:

            只有拥有DocumentReference 才能删除文档。为此,您必须首先执行查询,然后遍历QuerySnapshot,最后根据ref 删除每个DocumentSnapshot

            var jobskill_query = db.collection('job_skills').where('job_id','==',post.job_id);
            jobskill_query.get().then(function(querySnapshot) {
              querySnapshot.forEach(function(doc) {
                doc.ref.delete();
              });
            });
            

            【讨论】:

            • 感谢您的指点。不确定这里的选项是什么.. 也许这是 NodeJS? .. 在我使用 web JS 的情况下,必须使用 get(). 后跟 .then() 进行调用,如下所示:.get().then(function (querySnapshot) {}
            • 感谢您发布改进的答案。我的回答侧重于这样一个事实,即您需要先执行查询,然后才能删除其结果(单独删除)。很高兴看到您找到了一种针对您的上下文改进我的方法的方法,并感谢分享。
            • @OliverDixon 据我所知,Frank 提出了删除一系列回答 OP 问题的文档的关键要求(例如“删除位置”)......其他任何内容都可以由工程师来满足他们的需求。您添加的答案可能会帮助其他人在 Firebase Functions 中的特定用途,这真是太棒了......因为用户没有专门调用 Firebase Functions,它可能会使您的回复less平易近人 - 特别是因为它使用了一些独特的 ES2017/TS 特性。哦,仅供参考,Frank 是一位受人尊敬的 Firebase 工程师。 ?
            • 我不能说我没有尝试过! ?‍♂️? 您可能会在分析中考虑此答案与您的投票数相比。需要明确的是,我并没有说您的代码 only 适用于 Firebase 函数,而是您在此处的 cmets 和您的答案中明确指出了它。将其与弗兰克的回答进行比较,后者指出了“删除位置”的关键要求,并举例说明了用户可以适应他们的需求。懒惰的复制粘贴是一个问题......但弗兰克的回答解释了为什么用户需要做某事......您的回答只是提供了一种不同的代码方法,没有任何解释。 ?
            • 也只是一个注释,返回函数,以便在出现错误时将其标记在您的日志中。
            【解决方案11】:

            弗兰克回答中解决我问题的关键部分是doc.ref.delete() 中的.ref

            我最初只有doc.delete(),它给出了“不是函数”错误。现在我的代码看起来像这样并且完美运行:

            let fs = firebase.firestore();
            let collectionRef = fs.collection(<your collection here>);
            
            collectionRef.where("name", "==", name)
            .get()
            .then(querySnapshot => {
              querySnapshot.forEach((doc) => {
                doc.ref.delete().then(() => {
                  console.log("Document successfully deleted!");
                }).catch(function(error) {
                  console.error("Error removing document: ", error);
                });
              });
            })
            .catch(function(error) {
              console.log("Error getting documents: ", error);
            });
            

            【讨论】:

            • 这里的关键是你使用.ref.delete()
            • 这不会捕获错误吗?它不会等待 Foreach 迭代器完成。
            猜你喜欢
            • 2020-11-28
            • 2021-01-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-02-20
            • 2021-12-25
            • 2020-09-01
            相关资源
            最近更新 更多