使用Google云端存储从Firebase存储中删除文件夹

时间:2017-04-28 17:47:33

标签: java firebase google-cloud-storage firebase-storage firebase-admin

我想删除文件夹“test”及其中的所有内容。

我很幸运能够使用此代码在终端中删除FirebaseStorage中的文件夹及其所有内容/子文件夹:

gsutil rm -r gs://bucketname.appspot.com/test/**

enter image description here

但是,当我尝试在java中执行此操作时,它不起作用。

    Storage storage = StorageOptions.getDefaultInstance().getService();
    String bucketName = "bucketname.appspot.com/test";
    Bucket bucket = storage.get(bucketName);
    bucket.delete(Bucket.BucketSourceOption.metagenerationMatch());

它引发了这个异常:

Exception in thread "FirebaseDatabaseEventTarget" com.google.cloud.storage.StorageException: Invalid bucket name: 'bucketname.appspot.com/test'
    at com.google.cloud.storage.spi.DefaultStorageRpc.translate(DefaultStorageRpc.java:202)
    at com.google.cloud.storage.spi.DefaultStorageRpc.get(DefaultStorageRpc.java:322)
    at com.google.cloud.storage.StorageImpl$4.call(StorageImpl.java:164)
    at com.google.cloud.storage.StorageImpl$4.call(StorageImpl.java:161)
    at com.google.cloud.RetryHelper.doRetry(RetryHelper.java:179)
    at com.google.cloud.RetryHelper.runWithRetries(RetryHelper.java:244)
    at com.google.cloud.storage.StorageImpl.get(StorageImpl.java:160)
    at xxx.backend.server_request.GroupRequestManager.deleteGroupStorage(GroupRequestManager.java:119)
    at xxx.backend.server_request.GroupRequestManager.deleteGroup(GroupRequestManager.java:26)
    at xxx.backend.server_request.ServerRequestListener.onChildAdded(ServerRequestListener.java:27)
    at com.google.firebase.database.core.ChildEventRegistration.fireEvent(ChildEventRegistration.java:65)
    at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:49)
    at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:41)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "message" : "Invalid bucket name: 'bucketname.appspot.com/test'",
    "reason" : "invalid"
  } ],
  "message" : "Invalid bucket name: 'bucketname.appspot.com/test'"
}

那么它不存在?因为我在没有/ test的情况下运行这段代码:

    Storage storage = StorageOptions.getDefaultInstance().getService();
    String bucketName = "bucketname.appspot.com";
    Bucket bucket = storage.get(bucketName);
    bucket.exists(Bucket.BucketSourceOption.metagenerationMatch());

然后存在返回true,没有异常,我能够列出所有blob ..但我想删除“/ test”中的所有内容。

编辑:好的,我确实让它像这样工作,但我需要使用迭代器。有更好的解决方案吗?通配符还是什么?

    Storage storage = StorageOptions.getDefaultInstance().getService();
    String bucketName = "bucketname.appspot.com";
    Page<Blob> blobPage = storage.list(bucketName, Storage.BlobListOption.prefix("test/"));
    List<BlobId> blobIdList = new LinkedList<>();
    for (Blob blob : blobPage.iterateAll()) {
        blobIdList.add(blob.getBlobId());
    }
    storage.delete(blobIdList);

2 个答案:

答案 0 :(得分:2)

存储桶是保存数据的基本容器。你有一个名为“bucketname.appspot.com”的存储桶。 “bucketname.appspot.com/test”是您的存储桶名称加上一个文件夹,因此它不是您的存储桶的有效名称。通过调用bucket.delete(...),您只能删除整个存储桶,但无法删除存储桶中的文件夹。使用GcsService删除文件或文件夹。

String bucketName = "bucketname.appspot.com";
GcsService gcsService = GcsServiceFactory.createGcsService(RetryParams.getDefaultInstance());
gcsService.delete(new GcsFilename(bucketName, "test"));

答案 1 :(得分:1)

我在https://stackoverflow.com/a/52580756/4752490上发布了可能的解决方案,并将其也发布在这里。

这是使用Firebase功能删除Firebase存储中文件夹中文件的一种解决方案。

假定您具有存储在Firebase数据库中/ MyStorageFilesInDatabaseTrackedHere / path1 / path2下的模型。

这些模型将具有一个名为“ filename”的字段,该字段将具有Firebase Storage中文件的名称。

工作流程为:

  1. 在Firebase数据库中删除包含模型列表的文件夹
  2. 收听通过Firebase函数删除该文件夹的信息
  3. 此功能将遍历文件夹的子级,获取文件名并将其在存储中删除。

(免责声明:在此功能结束时,Storage中的文件夹仍然剩余,因此需要再次调用以将其删除。)

// 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);
});