Удалить папку из Firebase Storage с помощью Google Cloud Storage

Хочу удалить папку «тест» и все, что в ней есть.

Я успешно могу удалить папку и все ее содержимое / подпапки в FirebaseStorage с помощью терминала, используя этот код:

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

введите описание изображения здесь

Однако когда я попытался сделать это на 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());

then exists возвращает true, без исключения, и я могу перечислить все капли .. Но я хочу удалить все, что находится внутри "/ 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);

person Linxy    schedule 28.04.2017    source источник


Ответы (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"));
person Yevgen    schedule 28.04.2017
comment
является ли GcsService отдельным от com.google.cloud:google-cloud-storage sdk? Кажется, у меня его нет. (гибкий env) - person Linxy; 28.04.2017
comment
Это клиентская библиотека. Проверьте здесь: cloud.google.com/storage/docs/reference/libraries. - person Yevgen; 28.04.2017
comment
У меня уже установлена ​​эта клиентская библиотека, которую вы связали, и GcsService, похоже, не включен. Но я нашел его здесь: cloud.google.com/appengine/docs/standard/java/, помимо AppEngine SDK, но он находится в стандартной среде, и я использую гибкую среду. - person Linxy; 28.04.2017
comment
BlobId blobId = BlobId.of(bucketName, blobName); storage.delete(blobId); Blob должен быть доступен в обеих средах. - person Yevgen; 28.04.2017

Я разместил возможное решение на https://stackoverflow.com/a/52580756/4752490 и также опубликую его здесь. .

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

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

В этих моделях будет поле с именем «имя файла», в котором будет указано имя файла в хранилище 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);
});
person Lucy    schedule 30.09.2018
comment
Когда OP пометил свой вопрос как java, пожалуйста, уважайте этот тег и предоставьте java-решение, а не какой-то случайный код. - person francogrex; 23.01.2020