In Cloud Firestore, why is it not possible to “single bulk” delete a collection (as can be done with Realtime Database)?

前端 未结 3 1766
误落风尘
误落风尘 2020-12-10 11:37

With Firebase real time database we can delete a huge list of items with one single command simply by calling remove () on the parent node (the node is deleted

3条回答
  •  天涯浪人
    2020-12-10 12:24

    I was happily refactoring my app for Firestore from Realtime Database, enjoying the shorter code and simpler syntax, until I refactored the delete() functions! To delete a document with subcollections:

    • Create an array of promises.
    • get() a subcollection, that doesn't have further subcollections.
    • Iterate through a forEach() function to read each document in the subcollection.
    • Delete each document, and push the delete command into the array of promises.
    • Go on to the next subcollection and repeat this.
    • Use Promise.all(arrayOfPromises) to wait until all the subcollections have been deleted.
    • Then delete the top-level document.

    With multi layers of collections and documents you'll want to make that a function, then call it from another function to get the next higher layer, etc.

    You can see this in the console. To manually delete collections and documents, delete the right-most document, then delete the right-most collection, and so on working left.

    Here's my code, in AngularJS. It only works if the top-level collection wasn't deleted before the subcollections.

    $scope.deleteClip = function(docId) {
    if (docId === undefined) {
    docId = $scope.movieOrTvShow + '_' + $scope.clipInMovieModel;
    }
    $scope.languageVideos = longLanguageFactory.toController($scope.language) + 'Videos';
    var promises = [];
    firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).collection('SentenceTranslations').get()
    .then(function(translations) {
      translations.forEach(function(doc) {
        console.log(doc.id);
        promises.push(firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).collection('SentenceTranslations').doc(doc.id).delete());
      });
    });
    firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).collection('SentenceExplanations').get()
    .then(function(explanations) {
      explanations.forEach(function(doc) {
        console.log(doc.id);
        promises.push(firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).collection('SentenceExplanations').doc(doc.id).delete());
      });
    });
    Promise.all(promises).then(function() {
      console.log("All subcollections deleted.");
      firebase.firestore().collection($scope.languageVideos).doc($scope.movieOrTvShow).collection('Video Clips').doc(docId).delete()
      .then(function() {
        console.log("Collection deleted.");
        $scope.clipInMovieModel = null;
        $scope.$apply();
      })
      .catch(function(error) {
        console.log("Remove failed: " + error.message);
      });
    })
    .catch(function(error){
      console.log("Error deleting subcollections: " + error);
    });
    };
    

    All that would have been one line in Realtime Database.

提交回复
热议问题