使用 Google 云存储从 Firebase 存储中删除文件夹
Delete Folder from Firebase Storage using Google Cloud Storage
我想删除文件夹 "test" 以及其中的所有内容。
我使用以下代码成功删除了文件夹及其在 FirebaseStorage 中的所有内容 contents/subfolders:
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.call(StorageImpl.java:164)
at com.google.cloud.storage.StorageImpl.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.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());
然后存在 returns 是的,没有例外,我能够列出所有的 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);
存储桶是保存数据的基本容器。您有一个名为 "bucketname.appspot.com" 的存储桶。 "bucketname.appspot.com/test" 是您的存储桶名称加上一个文件夹,因此它不是您的存储桶的有效名称。调用bucket.delete(...)
只能删除整个bucket,不能删除bucket中的文件夹。使用 GcsService
删除文件或文件夹。
String bucketName = "bucketname.appspot.com";
GcsService gcsService = GcsServiceFactory.createGcsService(RetryParams.getDefaultInstance());
gcsService.delete(new GcsFilename(bucketName, "test"));
我在 上 post 提出了一个可能的解决方案,并且 post 也会在这里提出。
这是使用 Firebase 函数删除 Firebase 存储文件夹中文件的一种解决方案。
假设您的模型存储在 Firebase 数据库的 /MyStorageFilesInDatabaseTrackedHere/path1/path2 下。
这些模型将有一个名为 "filename" 的字段,该字段将具有 Firebase 存储中文件的名称。
工作流程是:
- 删除 Firebase 数据库中包含模型列表的文件夹
- 通过 Firebase 函数侦听该文件夹的删除
- 此函数将遍历文件夹的子文件夹,获取文件名并将其删除到存储中。
(免责声明:存储中的文件夹在此函数结束时仍然存在,因此需要再次调用以将其删除。)
// 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);
});
我想删除文件夹 "test" 以及其中的所有内容。
我使用以下代码成功删除了文件夹及其在 FirebaseStorage 中的所有内容 contents/subfolders:
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.call(StorageImpl.java:164)
at com.google.cloud.storage.StorageImpl.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.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());
然后存在 returns 是的,没有例外,我能够列出所有的 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);
存储桶是保存数据的基本容器。您有一个名为 "bucketname.appspot.com" 的存储桶。 "bucketname.appspot.com/test" 是您的存储桶名称加上一个文件夹,因此它不是您的存储桶的有效名称。调用bucket.delete(...)
只能删除整个bucket,不能删除bucket中的文件夹。使用 GcsService
删除文件或文件夹。
String bucketName = "bucketname.appspot.com";
GcsService gcsService = GcsServiceFactory.createGcsService(RetryParams.getDefaultInstance());
gcsService.delete(new GcsFilename(bucketName, "test"));
我在
这是使用 Firebase 函数删除 Firebase 存储文件夹中文件的一种解决方案。
假设您的模型存储在 Firebase 数据库的 /MyStorageFilesInDatabaseTrackedHere/path1/path2 下。
这些模型将有一个名为 "filename" 的字段,该字段将具有 Firebase 存储中文件的名称。
工作流程是:
- 删除 Firebase 数据库中包含模型列表的文件夹
- 通过 Firebase 函数侦听该文件夹的删除
- 此函数将遍历文件夹的子文件夹,获取文件名并将其删除到存储中。
(免责声明:存储中的文件夹在此函数结束时仍然存在,因此需要再次调用以将其删除。)
// 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);
});