如何将多个文件上传到 Firebase?

IT技术 javascript firebase firebase-storage
2021-02-21 16:14:35

有没有办法将多个文件上传到 Firebase 存储。它可以在一次尝试中上传单个文件,如下所示。

fileButton.addEventListener('change', function(e){ 
//Get file
var file = e.target.files[0];

//Create storage reference
var storageRef = firebase.storage().ref(DirectryPath+"/"+file.name);

//Upload file
var task = storageRef.put(file);

//Update progress bar
  task.on('state_changed',
    function progress(snapshot){

        var percentage = snapshot.bytesTransferred / snapshot.totalBytes * 100;
        uploader.value = percentage;
    },
    function error(err){

    },
    function complete(){
        var downloadURL = task.snapshot.downloadURL;

    }
  );

});

如何将多个文件上传到 Firebase 存储。

6个回答

我找到了上述问题的解决方案,我喜欢把它放在这里,因为它对任何人都有用。

//Listen for file selection
fileButton.addEventListener('change', function(e){ 
    //Get files
    for (var i = 0; i < e.target.files.length; i++) {
        var imageFile = e.target.files[i];

        uploadImageAsPromise(imageFile);
    }
});

//Handle waiting to upload each file using promise
function uploadImageAsPromise (imageFile) {
    return new Promise(function (resolve, reject) {
        var storageRef = firebase.storage().ref(fullDirectory+"/"+imageFile.name);

        //Upload file
        var task = storageRef.put(imageFile);

        //Update progress bar
        task.on('state_changed',
            function progress(snapshot){
                var percentage = snapshot.bytesTransferred / snapshot.totalBytes * 100;
                uploader.value = percentage;
            },
            function error(err){

            },
            function complete(){
                var downloadURL = task.snapshot.downloadURL;
            }
        );
    });
}
@isuru 你能分享你的 html 源文件吗?你在预览图像吗?
2021-04-24 16:14:35
非常感谢你!我花了一整天的时间试图了解 File 对象的整个过程,您的回答很有帮助。我唯一能想到的在这里添加的是整体上传进度,在这里实现起来并不容易。
2021-04-27 16:14:35
@user1040495 这不是真的,它们是并行上传的
2021-05-01 16:14:35
如果您像您一样放置多个并发上传任务,它们将依次上传
2021-05-07 16:14:35
@ArunaRajput 我使用上述方法将多个图像上传到 Firebase 存储。其实你想达到什么目的?
2021-05-09 16:14:35

Firebase Storage 使用 Promise,因此您可以使用 Promise 来实现它。

这是涵盖此主题的 firebase 博客文章: Keeping our Promises (and Callbacks)


给 Promise.all() 一个“Promise数组”

Promise.all(
  // Array of "Promises"
  myItems.map(item => putStorageItem(item))
)
.then((url) => {
  console.log(`All success`)
})
.catch((error) => {
  console.log(`Some failed: `, error.message)
});

上传每个文件并返回一个 Promise

putStorageItem(item) {
  // the return value will be a Promise
  return firebase.storage().ref("YourPath").put("YourFile")
  .then((snapshot) => {
    console.log('One success:', item)
  }).catch((error) => {
    console.log('One failed:', item, error.message)
  });
}

YourPath并且YourFile可以携带myItems数组(因此是item对象)。

我在这里省略了它们只是为了便于阅读,但你明白了这个概念。

您能否将此更新为当前的 Firebase 文档,或者至少分享如何获取当前正在运行的任务的进度以便相应地更新 UI
2021-05-11 16:14:35

我相信有一个更简单的解决方案:

// set it up
firebase.storage().ref().constructor.prototype.putFiles = function(files) { 
  var ref = this;
  return Promise.all(files.map(function(file) {
    return ref.child(file.name).put(file);
  }));
}

// use it!
firebase.storage().ref().putFiles(files).then(function(metadatas) {
  // Get an array of file metadata
}).catch(function(error) {
  // If any task fails, handle this
});
还没有测试过但看起来很优雅的方法,有没有办法可以跟踪上传进度?而不是使用then/catch我们可以使用on吗?
2021-05-05 16:14:35
        let ad_images=["file:///data/user/0/..../IMG-20181216-WA00001.jpg",
                       "file:///data/user/0/..../IMG-20181216-WA00002.jpg",
                       "file:///data/user/0/..../IMG-20181216-WA00003.jpg"];
        let firebase_images=[];

        const ref = firebase.firestore().collection('ads').doc(newRecord.id);
        putStorageItem = (url,index,ext) => {
            return firebase.storage().ref('YOURFOLDER/'+ index +'.'+ext ).putFile(url)
            .then((snapshot) => {
                console.log(snapshot)
                firebase_images[index] = snapshot.downloadURL;              
                //OR
                //firebase_images.push(snapshot.downloadURL);
            }).catch((error) => {
                console.log('One failed:', error.message)
            });
        }

        Promise.all(
            ad_images.map( async (item,index) => {
                let ext = item.split('/').pop().split(".").pop();
                console.log(newRecord.id, item, index, ext);
                await putStorageItem(newRecord.id, item, index, ext);
            })
        )
        .then((url) => {
            console.log(`All success`);
            console.log(firebase_images);
        })
          .catch((error) => {
            console.log(`Some failed: `, error.message)
        });

这是对那些希望在其他开始之前等待每个上传完成的人的标记答案的修改。

正如标记的答案一样,Promise没有得到解决或拒绝,所以当上传从循环开始时,一切都刚刚开始,第一个文件,第二个......

想想每个 20mb 上传 3 次。循环将几乎同时调用上传函数,使它们几乎同时运行。

这个答案解决了这个问题,async/await用于处理promises

fileButton.addEventListener('change', async function(e){ 
    //Get files
    for (var i = 0; i < e.target.files.length; i++) {
        var imageFile = e.target.files[i];
        await uploadImageAsPromise(imageFile).then((res)=>{
         console.log(res);
          });
    }
});

//Handle waiting to upload each file using promise
async function uploadImageAsPromise (imageFile) {
    return new Promise(function (resolve, reject) {
        var storageRef = firebase.storage().ref(fullDirectory+"/"+imageFile.name);
        var task = storageRef.put(imageFile);

        //Update progress bar
        task.on('state_changed',
            function progress(snapshot){
                var percentage = snapshot.bytesTransferred / snapshot.totalBytes * 
                     100;
            },
            function error(err){
                console.log(err);
                reject(err);
            },
            function complete(){
                var downloadURL = task.snapshot.downloadURL;
                resolve(downloadURL);
            }
        );
    });
}