当我尝试删除目录时,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不支持它,因为逐个删除目录中的文件会非常蹩脚(特别是如果所述目录有100或1000个这样的话)。
答案 0 :(得分:12)
,无法删除目录。您必须在某处(在Firebase数据库中)维护文件列表并逐个删除它们。
https://groups.google.com/forum/#!topic/firebase-talk/aG7GSR7kVtw
我还提交了功能请求,但由于他们的错误跟踪器不公开,因此没有可以分享的链接。
答案 1 :(得分:10)
在安全的Google云端功能环境中,您可以使用Google Cloud Storage npm软件包(也称为Google云端存储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`);
}
});
更多可用文档on GCS API docs
答案 2 :(得分:8)
在2020年,删除Firebase Storage文件夹似乎可以正常工作。我刚刚在下面的Cloud Functions(Node.js Admin)中做到了,它删除了其中的文件夹,子文件夹和文件。我确实使用npm下载了Google Cloud Storage,但是无论如何我都没有实际导入该库,而且Firebase Storage现在正在支持此功能,与上面每个人所说的不同。也许他们已经更新了。我对其进行了测试。
admin.initializeApp({
storageBucket: "bucket_name.appspot.com",
})
const bucket = admin.storage().bucket();
await bucket.deleteFiles({
prefix: `${folderName}/`
});
答案 3 :(得分:5)
执行此操作的方法如下(使用最后一个文件,删除dir):
let ref = firebase.storage().ref(path);
ref.listAll().then(dir => {
dir.items.forEach(fileRef => {
var dirRef = firebase.storage().ref(fileRef.fullPath);
dirRef.getDownloadURL().then(function(url) {
var imgRef = firebase.storage().refFromURL(url);
imgRef.delete().then(function() {
// File deleted successfully
}).catch(function(error) {
// There has been an error
});
});
});
}).catch(error => {
console.log(error);
});
答案 4 :(得分:4)
现在您知道我们无法删除Firebase存储中的文件夹。但是您可以在该文件夹中列出文件,然后删除每个文件。
这里有一个样品。
// Create a root reference
var storageRef = firebase.storage().ref();
// Create a reference
var mountainsRef = storageRef.child("your root path");
// Now we get the references of these files
mountainsRef.listAll().then(function (result) {
result.items.forEach(function (file) {
file.delete();
});
}).catch(function (error) {
// Handle any errors
});
Flutter Firebase存储listAll()
方法目前在软件包的开发版本5.0.0-dev.1
中可用,您可以如上所示使用它。
答案 5 :(得分:2)
基于 TheFastCat 的回答和 Teodor Ciuraru 的评论,我创建了以下Firebase Cloud Function,当从Firebase身份验证中删除用户时,该功能将删除用户的文件夹
const admin = require('firebase-admin')
const functions = require('firebase-functions')
const bucket = admin.storage().bucket()
exports.deleteUser = functions.auth.user().onDelete(async (user) => {
const { uid } = user
await bucket.deleteFiles({
prefix: `${uid}/`
})
})
答案 6 :(得分:1)
从2019年7月开始,您可以列出一个文件夹并递归删除其内容:
gl.copyTexSubImage2D
答案 7 :(得分:0)
在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);
});
}
答案 8 :(得分:0)
如上所述,删除目录无效。我分享了一个查询Firebase数据库中的文件列表并逐个删除它们的示例。这是我的查询和电话。
Get-AzureVM
这是我的函数循环,通过获取URL,然后删除该存储引用的文件。
$serviceName = "xxxx"
$vmName ="xxxx"
$vm= Get-AzureVM -ServiceName $serviceName -Name $vmName
$disk = Get-AzureDisk -DiskName $vm.VM.OSVirtualHardDisk.DiskName
$location = $disk.Location
答案 9 :(得分:0)
这是使用Firebase功能删除Firebase存储中文件夹中文件的一种解决方案。
假定您具有存储在Firebase数据库中/ MyStorageFilesInDatabaseTrackedHere / path1 / path2下的模型。
这些模型将具有一个名为“ filename”的字段,该字段将具有Firebase Storage中文件的名称。
工作流程为:
(免责声明:在此功能结束时,Storage中的文件夹仍然剩余,因此需要再次调用以将其删除。)
export class MyWidgetComponent implements OnChanges {
cssExternal$: Observable<any>;
ngOnChanges(changes: SimpleChanges) {
const contentChanges = changes.content;
if (contentChanges) {
// ...some code
this.url$ = new Subject();
this.cssInternal$ = new Subject();
this.cssExternal$ = this.url$.pipe(
map((url: string) => {
console.log('url in map', url);
if (url.includes(window.location.origin)) {
return url.replace(window.location.origin, this.url);
}
return url;
}),
mergeMap((url: string) => {
return this._ApiService.makeRequest(url, ActionType.content).pipe(
map(({ content }: any) => content)
);
})
);
this.css$ = merge(
this.cssInternal$,
this.cssExternal$
);
this.parseStyles(styleSheets);
}
parseStyles(styleSheets: Element[]) {
return styleSheets.forEach((element: HTMLElement) => {
switch (element.localName) {
// ...some code
case 'link':
const url = (element as HTMLLinkElement).href;
console.log('url before next', url);
this.url$.next(url);
break;
// ...some code
}
});
}
}
答案 10 :(得分:0)
似乎删除目录的唯一方法是循环浏览所有文件并逐个删除它们:
const mapStateToProps = (state, props) => ({
note: state.notes.find((note) => note.id === props.match.params.id
});
答案 11 :(得分:0)
我注意到,在删除 firebase 存储文件夹中的所有文件时,一段时间后,该文件夹也被删除。无需任何操作。
答案 12 :(得分:-1)
现代版本的“ Miki”答案,使用带有for await... of..
的ES2018 Async/Await
和已删除文件计数器 。
const storage = firebase.storage();
const deleteFile = async (filePath) => {
const ref = storage.ref(filePath);
return await ref.delete();
};
const deleteFolderRecursive = async (folderPath) => {
const ref = storage.ref(folderPath);
const list = await ref.listAll();
let filesDeleted = 0;
for await (const fileRef of list.items) {
await deleteFile(fileRef.fullPath);
filesDeleted++;
}
for await (const folderRef of list.prefixes) {
filesDeleted += await deleteFolderRecursive(folderRef.fullPath);
}
return filesDeleted;
};
// Usage
async deleteFolder(x) {
try {
const filesDeleted = deleteFolderRecursive('path/to/storage/folder');
console.log(`${filesDeleted} files has been deleted`);
// you can now, for instance, unblock the UI at this point
} catch(err){
// probably denied permissions or 'path/to/storage/folder' is not a folder
console.error(err)
}
}
如前所述,文件夹引用不会被删除,但至少它们不会像无法访问的文件那样从您的存储配额中拖出。