programing

Firebase 저장소:디렉터리를 삭제하는 방법

closeapi 2023. 6. 5. 23:55
반응형

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`);
    }
  });

GCS API 문서에서 사용할 수 있는 추가 설명서

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" 필드가 있습니다.

워크플로우는 다음과 같습니다.

  1. 모델 목록이 들어 있는 Firebase 데이터베이스의 폴더 삭제
  2. Firebase Functions를 통해 해당 폴더의 삭제를 기다립니다.
  3. 이 함수는 폴더의 하위 항목을 루프하여 파일 이름을 가져온 다음 저장소에서 삭제합니다.

(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

반응형