Firebase Web:将多个文件上传到存储,然后下载其URL [英] Firebase web: upload multiple files to Storage an then download their URLs

查看:62
本文介绍了Firebase Web:将多个文件上传到存储,然后下载其URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个博客网站,并正在编写按顺序执行以下操作的代码:

1。存储用户上传

2的多张照片。下载其网址

3。将它们保存到实时数据库中。

I am creating a blogging website, and am writing code that does the following in order:
1. stores multiple photos that the user uploads
2. download their URLs
3. save them to the realtime database.

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

I wrote the function below to do #1 and #2. Basically the idea is to store all the urls to an array, in this case '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数组。 (为了使情况简洁,我省略了其余代码)

Here is the part of the upload function code that would upload all the relevant data to the database, including the array of URLs returned by the promise in the function above. (I omitted the rest of the code to make the case concise)

        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以外的所有内容写入数据库',它应该是URL的数组。

这是我在进行调试时发现的内容:

-照片存储没有问题。

-urls为每个文件下载文件,并按预期在执行代码中成功返回urlarray。

可能出了什么问题?我在这里迷路了。任何建议都将非常受欢迎。
非常感谢!

Here is the issue: The code would write to database everything except the 'photolink', which should be the array of URLs.
Here is what I found out doing debugging:
-Photos are stored without any problem.
-urls are downloaded for each file, and urlarray is returned successfully in the execution code as expected.
What might have gone wrong? I am lost here. Any advice would be very much welcome. Thanks a lot!

推荐答案

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

Each time you call storageRef.put(...) it starts an asynchronous operation. Right now your `` doesn't wait for these asynchronous operations to complete, and instead returns the list of URLS before it's been populated.

最简单的方法是添加一些简单的方法记录到您的代码:

The easiest way to see this is by adding some simple logging to your code:

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

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

When you run this code, the output will look like:


开始放置文件...

Starting to put file...

开始放置文件...

开始放置文件...

使用0个下载URL进行解析

Resolving with 0 download URLs

完成上传,获取下载URL ...

Upload done, getting download URL...

下载URL已获取,添加到数组中...

Download URL gotten, adding to array...

上传完成,获取下载URL ...

Upload done, getting download URL...

获取URL,添加到数组中。

Download URL gotten, adding to array...

上传完成,获取下载URL ...

Upload done, getting download URL...

获得下载URL,添加至数组...

Download URL gotten, adding to array...

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

That is not the order you want of course, as you're returning the array before you added any download URL to it, and even before any of the uploads complete.

解决方案是(与异步操作一样,总是)等到所有操作完成后再解析/返回。使用 Promise.all()可以很容易地做到这一点,就像这样:

The solution is (as always when it comes to asynchronous operations) to wait until all operations have finished before resolving/returning. You can most easily do this with Promise.all() with something like this:

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

这篇关于Firebase Web:将多个文件上传到存储,然后下载其URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆