【问题标题】:Firebase web: upload multiple files to Storage an then download their URLsFirebase web:将多个文件上传到存储,然后下载它们的 URL
【发布时间】:2020-05-29 03:16:49
【问题描述】:

我正在创建一个博客网站,并且正在编写按顺序执行以下操作的代码:
1。存储用户上传的多张照片
2。下载他们的网址
3。将它们保存到实时数据库中。

我编写了下面的函数来执行 #1 和 #2。基本上这个想法是将所有 url 存储到一个数组中,在本例中为 'urlarray'。

function url_array_get(){
return new Promise(function(resolve,reject){
    let filez=review_photo.files;
    let urlarray=[];
    let user=firebase.auth().currentUser;
    let files=Array.from(filez);
    files.forEach(function(file) {
        let storageRef=firebase.storage().ref('data/'+user.uid+'/posts/'+file.name);
            storageRef.put(file).then(function(snapshot){
                snapshot.ref.getDownloadURL().then(function(url) {
                    urlarray.push(url);
                })
            })
        });
    if (!urlarray){
        reject("oops");
    }
    else {
        resolve(urlarray);
    }
});
}

这是上传函数代码的一部分,它将所有相关数据上传到数据库,包括上面函数中的 promise 返回的 URL 数组。 (我省略了其余代码以使案例简洁)

        let userpostRef=firebase.database().ref('posts/');
        let newpostRef=userpostRef.push();
                    newpostRef.set({
                        userid: user.uid,
                        post_target: rtarget,
                        post_content:rtext,
                        time: firebase.database.ServerValue.TIMESTAMP
                    }).then(function(){
                            url_array_get().then(function(result){
                            newpostRef.once('value', function(snapshot) {
                                newpostRef.update({
                                    postnum:snapshot.key,
                                    photolink:result
                                })
                        })})}).
            then(function(){
                alert("Upload successful!");
                window.location.href='/'+username;
            })
            .catch(function(error){
                alert("Error!");    
            });               
        }

问题是:代码会将除“photolink”之外的所有内容写入数据库,“photolink”应该是 URL 数组。
这是我在调试时发现的:
-照片存储没有任何问题。
为每个文件下载-urls,并按预期在执行代码中成功返回urlarray。
可能出了什么问题?我在这里迷路了。任何建议都会非常受欢迎。 非常感谢!

【问题讨论】:

    标签: javascript firebase firebase-realtime-database firebase-storage es6-promise


    【解决方案1】:

    每次调用storageRef.put(...) 时,它都会启动一个异步操作。现在您的 `` 不会等待这些异步操作完成,而是在填充之前返回 URL 列表。

    查看这一点的最简单方法是在代码中添加一些简单的日志记录:

    function url_array_get(){
      return new Promise(function(resolve,reject){
        let filez=review_photo.files;
        let urlarray=[];
        let user=firebase.auth().currentUser;
        let files=Array.from(filez);
        files.forEach(function(file) {
            console.log("Starting to put file...");
            let storageRef=firebase.storage().ref('data/'+user.uid+'/posts/'+file.name);
                storageRef.put(file).then(function(snapshot){
                    console.log("Upload done, getting download URL...");
                    snapshot.ref.getDownloadURL().then(function(url) {
                        console.log("Download URL gotten, adding to array...");
                        urlarray.push(url);
                    })
                })
            });
        if (!urlarray){
            reject("oops");
        }
        else {
            console.log("Resolving with "+urlarray.length+" download URLs");
            resolve(urlarray);
        }
      });
    }
    

    当您运行此代码时,输​​出将如下所示:

    开始放文件...

    开始放文件...

    开始放文件...

    使用 0 个下载 URL 解析

    上传完成,正在获取下载地址...

    获取的下载地址,添加到数组中...

    上传完成,正在获取下载地址...

    获取的下载地址,添加到数组中...

    上传完成,正在获取下载地址...

    获取的下载地址,添加到数组中...

    这当然不是您想要的顺序,因为您在向其添加任何下载 URL 之前返回数组,甚至在任何上传完成之前。


    解决方案是(与异步操作一样)等到所有操作完成后再解析/返回。您可以使用 Promise.all() 最轻松地做到这一点,如下所示:

    function url_array_get(){
        let promises = [];
        let filez=review_photo.files;
        let user=firebase.auth().currentUser;
        let files=Array.from(filez);
        files.forEach(function(file) {
            let storageRef=firebase.storage().ref('data/'+user.uid+'/posts/'+file.name);
            promises.push(
                storageRef.put(file).then(function(snapshot){
                    return snapshot.ref.getDownloadURL()
                })
            });
        });
        return Promise.all(promises);
    }
    

    或略短:

    function url_array_get(){
        let user=firebase.auth().currentUser;
        let ref = firebase.storage().ref('data/'+user.uid+'/posts/');
        let files=Array.from(review_photo.files);
        let promises = files.map(function(file) {
            return ref.child(file.name).put(file).then(function(snapshot){
                return snapshot.ref.getDownloadURL()
            })
        });
        return Promise.all(promises);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      • 2018-12-28
      • 2020-11-19
      • 1970-01-01
      • 2020-05-24
      相关资源
      最近更新 更多