FirebaseStorage: Как удалить каталог

FirebaseStorage всегда возвращает ошибку 400 когда я пытаюсь удалить каталог, т. е. что-то вроде следующего всегда возвращает ошибку 400.

let storageRef = FIRStorage.storage().reference().child("path/to/directory")
storageRef.deleteWithCompletion { (error) in
    print("error: (error)") // always prints error code 400
}

однако удаление файлов работает нормально, например, что-то вроде не возвращает ошибку:

let storageRef = FIRStorage.storage().reference().child("path/to/file.jpg")
storageRef.deleteWithCompletion { (error) in
    print("error: (error)") // works fine, error is nil
}

что я могу здесь делать не так? Я не считаю, что он не поддерживается FirebaseStorage, потому что удаление файлов из каталога один за другим было бы довольно хромым (особенно, если указанный каталог имеет 100s или 1000 из них).

5 ответов


из группы google удаление каталога невозможно. Вы должны поддерживать список файлов где-то (в базе данных Firebase) и удалять их один за другим.

https://groups.google.com/forum#!тема / firebase-talk/aG7GSR7kVtw

Я также отправил запрос на функцию, но поскольку их трекер ошибок не является общедоступным, нет никакой ссылки, которую я мог бы поделиться.


из контекста безопасной функции Google cloud-вы можете удалить весь каталог с помощью пакета Google Cloud Storage npm (он же Google Cloud Storage API), например:

const gcs = require('@google-cloud/storage')();
const functions = require('firebase-functions');
...
  const bucket = gcs.bucket(functions.config().firebase.storageBucket);

  return bucket.deleteFiles({
    prefix: `users/${userId}/`
  }, function(err) {
    if (err) {
      console.log(err);
    } else {
      console.log(`All the Firebase Storage files in users/${userId}/ have been deleted`);
    }
  });

доступна дополнительная документация на GCS API docs


в 26/5/2017 нет способа удалить каталог, но вы можете использовать мой алгоритм

используйте этот код.

   this.sliders = this.db.list(`users/${this.USER_UID}/website/sliders`) as FirebaseListObservable<Slider[]>



  /**
   * Delete image from firebase storage is take a string path of the image
   * @param _image_path
   */
  deleteImage(_image_path: string) {

    // first delete the image
    const storageRef = firebase.storage().ref();
    const imageRef = storageRef.child(_image_path);
    imageRef.delete().then(function() {
      console.log('file deleted');
      // File deleted successfully
    }).catch(function(error) {
      // Uh-oh, an error occurred!
      console.log(error);
    });

  }



  /**
   * Deletes multiple Sliders, it takes an array of ids
   * @param ids
   */
  deleteMutipleSliders(ids: any) {

    ids.forEach(id => {

      this.getSliderDetails(id).subscribe(slider => {

        let id = slider.$key; // i think this is not nesesery
        const imgPath = slider.path;

        this.deleteImage(imgPath);
      });

      return this.sliders.remove(id);

    });


  }

Как указано выше, удаление каталога не действует. Я делюсь примером запроса списка файлов в базе данных Firebase и удаления их один за другим. Это мой запрос и вызов.

    let messagePhotoQuery = messagesRef.child(group.key).child("messages").queryOrdered(byChild: "photoURL")
    deleteMessagePhotos(from: messagePhotoQuery)

Это моя функция, циклически получающая URL-адрес, а затем удаляющая файл в этой ссылке на хранилище.

    func deleteMessagePhotos(from photoQuery: FIRDatabaseQuery) {
    photoQuery.observeSingleEvent(of: .value, with: { (messagesSnapshot) in
        guard messagesSnapshot.exists() else { return }
        print(messagesSnapshot)
        for message in messagesSnapshot.children {
            let messageSnapshot = message as! FIRDataSnapshot
            let messageData = messageSnapshot.value as! [String: AnyObject]
            if let photoURL = messageData["photoURL"] as? String {
                let photoStorageRef = FIRStorage.storage().reference(forURL: photoURL)
                photoStorageRef.delete(completion: { (error) in
                    if let error = error {
                        print(error)
                    } else {
                        // success
                        print("deleted \(photoURL)")
                    }
                })
            }
        }
    })
}

вот одно из решений для удаления файлов в папке в хранилище Firebase с помощью функций Firebase.

предполагается, что модели хранятся в /MyStorageFilesInDatabaseTrackedHere/path1 / path2 в базе данных Firebase.

эти модели будут иметь поле с именем "filename", которое будет иметь имя файла в хранилище Firebase.

процесс:

  1. удалить папку в базе данных Firebase, содержащую список модели
  2. слушайте удаление этой папки через функции Firebase
  3. эта функция будет перебирать дочерние элементы папки, получать имя файла и удалять его в хранилище.

(отказ от ответственности: папка в хранилище все еще остается в конце этой функции, поэтому для ее удаления необходимо выполнить другой вызов.)

// 1. Define your Firebase Function to listen for deletions on your path
exports.myFilesDeleted = functions.database
    .ref('/MyStorageFilesInDatabaseTrackedHere/{dbpath1}/{dbpath2}')
    .onDelete((change, context) => {

// 2. Create an empty array that you will populate with promises later
var allPromises = [];

// 3. Define the root path to the folder containing files
// You will append the file name later
var photoPathInStorageRoot = '/MyStorageTopLevelFolder/' + context.params.dbpath1 + "/" + context.params.dbpath2;

// 4. Get a reference to your Firebase Storage bucket
var fbBucket = admin.storage().bucket();

// 5. "change" is the snapshot containing all the changed data from your
// Firebase Database folder containing your models. Each child has a model
// containing your file filename
if (change.hasChildren()) {
    change.forEach(snapshot => {

        // 6. Get the filename from the model and
        // form the fully qualified path to your file in Storage
        var filenameInStorage = photoPathInStorageRoot + "/" + snapshot.val().filename;

        // 7. Create reference to that file in the bucket
        var fbBucketPath = fbBucket.file(filenameInStorage);

        // 8. Create a promise to delete the file and add it to the array
        allPromises.push(fbBucketPath.delete());
    });
}

// 9. Resolve all the promises (i.e. delete all the files in Storage)
return Promise.all(allPromises);
});