Delete Folder from Firebase Storage using Google Cloud Storage

青春壹個敷衍的年華 提交于 2019-12-04 01:42:55

问题


I want to delete the folder "test" and everything that is in it.

I am sucessfuly able to delete the folder and all it's contents/subfolders in FirebaseStorage with the terminal using this code:

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

However when I tried to do it in java, it does not work.

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

It throws this exception:

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'"
}

So then it does not exist? because when I run this code without /test:

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

then exists returns true, no exception and I am able to list all the blobs.. But I want to delete all that is inside "/test".

Edit: Okay, I did get it to work like this, but I need to use a iterator. Is there a better solution? A wildcard or something?

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

回答1:


Buckets are the basic containers that hold your data. You have a bucket with name "bucketname.appspot.com". "bucketname.appspot.com/test" is your bucket name plus a folder, so its not a valid name of your bucket. By calling bucket.delete(...) you can delete only the whole bucket, but you cannot delete a folder in a bucket. Use GcsService to delete files or folders.

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



回答2:


I posted a possible solution over at https://stackoverflow.com/a/52580756/4752490 and will post it here too.

Here is one solution to delete files in a folder in Firebase Storage using Firebase Functions.

It assumes you have models stored under /MyStorageFilesInDatabaseTrackedHere/path1/path2 in your Firebase Database.

Those models will have a field named "filename" which will have the name of the file in Firebase Storage.

The workflow is:

  1. Delete the folder in Firebase Database that contains the list of models
  2. Listen for the deletion of that folder via Firebase Functions
  3. This function will loop over the children of the folder, obtain the filename and delete it in Storage.

(Disclaimer: the folder in Storage is still leftover at the end of this function so another call needs to be made to remove it.)

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


来源:https://stackoverflow.com/questions/43686101/delete-folder-from-firebase-storage-using-google-cloud-storage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!