Firebase 저장소:디렉터리를 삭제하는 방법
Firebase Storage에서 항상 오류를 반환합니다.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
}
제가 여기서 뭘 잘못하고 있을까요?디렉토리에서 파일을 하나씩 삭제하는 것은 매우 어려울 것이기 때문에 Firebase Storage에서 지원하지 않는다고 생각합니다(특히 해당 디렉토리에 100개 또는 1000개의 파일이 있는 경우).
보안 Google 클라우드 기능의 맥락에서 - 다음과 같이 Google Cloud Storage npm 패키지(일명 Google Cloud Storage 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`);
}
});
2020년에는 Firebase Storage 폴더를 삭제하는 것이 효과가 있을 것으로 보입니다.아래의 클라우드 기능(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}/`
});
폴더를 나열하고 폴더 내용을 재귀적으로 삭제할 수 있습니다.
deleteFolder(path) {
const ref = firebase.storage().ref(path);
ref.listAll()
.then(dir => {
dir.items.forEach(fileRef => this.deleteFile(ref.fullPath, fileRef.name));
dir.prefixes.forEach(folderRef => this.deleteFolder(folderRef.fullPath))
})
.catch(error => console.log(error));
}
deleteFile(pathToFile, fileName) {
const ref = firebase.storage().ref(pathToFile);
const childRef = ref.child(fileName);
childRef.delete()
}
Google 그룹에서 디렉토리를 삭제할 수 없습니다.파일 목록을 (Firebase Database의) 어딘가에 유지 관리하고 하나씩 삭제해야 합니다.
https://groups.google.com/forum/ #!항목/파이어베이스 토크/aG7GSR7kVtw
기능 요청도 제출했지만 버그 트래커가 공개되지 않아 공유할 수 있는 링크가 없습니다.
이제 방화벽 저장소의 폴더를 삭제할 수 없습니다.그러나 해당 폴더 내의 파일을 나열하고 각 파일을 제거할 수 있습니다.
여기 샘플이 있습니다.
// 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
});
Floating Firebase 저장소listAll()
메소드는 현재 패키지의 개발 버전, 버전에서 사용할 수 있습니다.5.0.0-dev.1
위와 같이 사용할 수 있습니다.
이 작업을 수행하는 방법은 다음과 같습니다(마지막 파일을 사용하여 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);
});
저는 더 패스트캣의 답변과 테오도르 시우라루의 코멘트를 바탕으로 파이어베이스 인증에서 사용자가 삭제될 때 사용자의 폴더를 삭제하는 파이어베이스 클라우드 기능을 아래에 만들었습니다.
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}/`
})
})
빈 폴더가 자동으로 삭제됩니다.따라서 폴더에서 모든 파일을 삭제하면 폴더 자체도 삭제됩니다.
2017년 5월 26일에는 디렉터리를 삭제할 방법이 없지만 내 알고리즘을 사용할 수 있습니다.
이 코드를 사용합니다.
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);
});
}
Firebase 기능을 사용하여 Firebase 저장소의 폴더에 있는 파일을 삭제할 수 있는 한 가지 솔루션이 있습니다.
여기에서는 모델이 Firebase 데이터베이스의 /MyStorageFilesInDatabaseTrackedHere/path1/path2에 저장되어 있다고 가정합니다.
이러한 모델에는 Firebase Storage에 있는 파일 이름을 가진 "filename" 필드가 있습니다.
워크플로우는 다음과 같습니다.
- 모델 목록이 들어 있는 Firebase 데이터베이스의 폴더 삭제
- Firebase Functions를 통해 해당 폴더의 삭제를 기다립니다.
- 이 함수는 폴더의 하위 항목을 루프하여 파일 이름을 가져온 다음 저장소에서 삭제합니다.
(Disclaimer: Storage의 폴더는 이 기능이 끝날 때까지 남아 있으므로 제거하기 위해 다른 전화를 걸어야 합니다.)
// 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);
});
파이어베이스 저장소 폴더의 모든 파일을 삭제할 때 잠시 후 폴더도 삭제됩니다.작업이 필요하지 않습니다.
위에서 설명한 것처럼 디렉터리를 삭제하는 것은 유효하지 않습니다.Firebase Database에서 파일 목록을 조회하여 하나씩 삭제하는 예제를 공유합니다.이것이 저의 질의 전화입니다.
let messagePhotoQuery = messagesRef.child(group.key).child("messages").queryOrdered(byChild: "photoURL")
deleteMessagePhotos(from: messagePhotoQuery)
이것은 URL을 가져오는 과정을 반복한 다음 해당 저장소 참조에서 파일을 삭제하는 기능입니다.
func deleteMessagePhotos(from photoQuery: FIRDatabaseQuery) {
photoQuery.observeSingleEvent(of: .value, with: { (messagesSnapshot) in
guard messagesSnapshot.exists() else { return }
print(messagesSnapshot)
for message in messagesSnapshot.children {
let messageSnapshot = message as! FIRDataSnapshot
let messageData = messageSnapshot.value as! [String: AnyObject]
if let photoURL = messageData["photoURL"] as? String {
let photoStorageRef = FIRStorage.storage().reference(forURL: photoURL)
photoStorageRef.delete(completion: { (error) in
if let error = error {
print(error)
} else {
// success
print("deleted \(photoURL)")
}
})
}
}
})
}
디렉토리를 삭제하는 유일한 방법은 모든 파일을 루프하여 하나씩 삭제하는 것입니다.
async function DeleteFirebaseStorageFolder(directoryName: string) {
const serviceAccount = require('../secret/adminSdkPrivateKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
storageBucket: 'gs://yourprojectname.appspot.com'
});
const bucket = admin.storage().bucket();
const files = (await bucket.getFiles({ directory: folderName }))[0];
const Deletions = [];
files.forEach(file => {
Deletions.push(bucket.file(file.name).delete());
})
await Promise.all(Deletions);
bucket.getFiles({ directory: folderName }).then((files) => {
console.log('Remaining number of files: ' + (files[0].length).toString());
})
}
DeleteFirebaseStorageFolder('myDirectoryName');
ES2018 with and deleted files 카운터를 사용하는 현대판 'Miki' 답변입니다.
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)
}
}
앞에서 언급했듯이 폴더 참조는 삭제되지 않지만 연결할 수 없는 파일처럼 저장소 할당량에서 끌어오지는 않습니다.
집에서 이것을 하지 마세요!
파이어베이스 9
클라이언트 측을 사용하여 폴더를 삭제하는 예:
- 수백만 개의 파일이 있는 경우 권장되지 않을 수 있습니다.
async function deleteFolder(path: string) {
const folderRef = ref(storage, path)
const fileList = await listAll(folderRef)
const promises = []
for(let item of fileList.items) {
promises.push(deleteObject(item))
}
const result = await Promise.all(promises)
return result
}
언급URL : https://stackoverflow.com/questions/37749647/firebasestorage-how-to-delete-directory
'programing' 카테고리의 다른 글
파이어베이스 이후로 지금 어떤 방법을 사용해야 합니까?InstanceId.getInstance().getToken()이 더 이상 사용되지 않습니다. (0) | 2023.06.05 |
---|---|
클래스 조롱:모의() 또는 패치()? (0) | 2023.06.05 |
R 사용자 전문가, 의 기능.R 프로파일? (0) | 2023.06.05 |
dplyr을 사용하여 중복된 행 제거 (0) | 2023.06.05 |
종료 메시지 작성 방법 (0) | 2023.06.05 |