我正在尝试使用 Flutter 和 Firebase 制作一个存储系统。当用户将文件上传到应用程序时,该文件将存储在 Firebase Storage 中,并在 Firestore 中为该文件创建一个文档,并在应用程序中显示该文件。同样,当用户创建文件夹时,Firestore 中会为该文件夹创建一个文档,如果用户要将文件上传到该文件夹,则将文件文档中的“filePath”字段设置为该文件夹的 doc id 。同样,用户可以在该文件夹内创建其他文件夹。您可以在文件夹 A 内创建文件夹 B 并将文件放在那里。经典的云存储逻辑。这是我遇到问题的地方。正如您在应用程序中创建文件和文件夹一样,您当然也可以删除它们。我还想设置它,以便在删除文件夹时删除其中的所有内容,但我还没有弄清楚如何循环删除文件夹内子文件夹中的其他文件夹和文件。我的意思是这样的,例如,假设您有文件夹 A,该文件夹内有文件夹 B,B 内有文件夹 C,依此类推,直到文件夹 Z。当用户想要删除文件夹 A 时,我想要它们从最里面的文件夹开始删除文件(在我给出的示例中,这是文件夹 Z,但它可以永远继续下去),然后一直到 A 并最后删除文件夹 A。
正如我在下面的代码示例中提到的,我编写了一段代码,以便当删除文件夹A时,其中的文件夹和文件都被删除,但是我编写的代码并没有删除Storage上的文件夹的数据,它只删除Firestore 中的文档并阻止通过应用程序查看该文件夹。所以它无法正常工作。
FirebaseStorage storage = FirebaseStorage.instance;
// Identify the folder containing the files
String path = 'cloud/files/$userId/$docId/';
//If there is a file in the folder, list it
bool hasFiles = await storage.ref(path).listAll().then((value) {
return value.items.isNotEmpty;
});
// Delete files
if (hasFiles) {
storage.ref(path).listAll().then((value) {
// Dosyalar başarıyla silindi.
for (var element in value.items) {
storage.ref(element.fullPath).delete();
}
}, onError: (error) {
Navigator.pop(context);
});
//Delete Firestore data of subfolders within the folder
QuerySnapshot querySnapFolders = await FirebaseFirestore.instance.collection('folders').where('folderPath', isEqualTo: docId).get();
QueryDocumentSnapshot docFolders = querySnapFolders.docs[0];
DocumentReference docRefFolders = docFolders.reference;
docRefFolders.delete();
//Delete Firestore data of files in the folder
QuerySnapshot querySnapFiles = await FirebaseFirestore.instance.collection('cloud').where('filePath', isEqualTo: docId).get();
QueryDocumentSnapshot docFiles = querySnapFiles.docs[0];
DocumentReference docRefFiles = docFiles.reference;
docRefFiles.delete();
}
//Delete the folder's own Firestore data and complete the process
QuerySnapshot querySnap = await FirebaseFirestore.instance.collection('folders').where('docId', isEqualTo: docId).get();
QueryDocumentSnapshot doc = querySnap.docs[0];
DocumentReference docRef = doc.reference;
docRef.delete().whenComplete(() => Navigator.pop(context));
我应该提到,我将子文件夹存储在与存储库中主文件夹相同的位置。所有文件夹都位于代码中指定的“cloud/files/$userId/$docId”位置,使用它们自己的文档 ID。我通过将“folderPath”字段设置为主文件夹的文档 ID 来显示 Firestore 文档中的文件夹。每个文件夹的文件夹路径等于其所在文件夹的id。文件夹B的folderPath值为A的id。
问题好像有点复杂。如果有我无法解释的部分,我很抱歉。如果您有任何疑问,我将很乐意回答。我等待您的支持。
首先,整个语句的结果是一个Future:
storage.ref(path).listAll().then((value) {
// Dosyalar başarıyla silindi.
for (var element in value.items) {
storage.ref(element.fullPath).delete();
}
}, onError: (error) {
Navigator.pop(context);
});
所以至少我们需要等待。不过回调内部,还有一系列的Future:
storage.ref(element.fullPath).delete();
所以,我建议尝试:
try {
final listResult = await storage.ref(path).listAll();
await Future.wait(
listResult.items.map((e) => storage.ref(e.fullPath).delete()));
} on Exception {
Navigator.pop(context);
}