Firebase 网络:将多个文件上传到存储然后下载它们的 URL
Firebase web: upload multiple files to Storage an then download their URLs
我正在创建一个博客网站,并且正在编写按顺序执行以下操作的代码:
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);
}
});
}
这是上传功能代码的一部分,它将所有相关数据上传到数据库,包括上面函数中承诺返回的 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 数组。
这是我在调试时发现的:
-照片存储没有任何问题。
- 为每个文件下载url,在执行代码中如预期成功返回urlarray。
可能出了什么问题?我在这里迷路了。非常欢迎任何建议。
非常感谢!
每次调用 storageRef.put(...)
它都会启动一个异步操作。现在你的 `` 不会等待这些异步操作完成,而是 returns URLS 的列表在它被填充之前。
查看此内容的最简单方法是在您的代码中添加一些简单的日志记录:
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);
}
});
}
当您 运行 此代码时,输出将如下所示:
Starting to put file...
Starting to put file...
Starting to put file...
Resolving with 0 download URLs
Upload done, getting download URL...
Download URL gotten, adding to array...
Upload done, getting download URL...
Download URL gotten, adding to array...
Upload done, getting download URL...
Download URL gotten, adding to array...
这当然不是您想要的顺序,因为您在向数组添加任何下载 URL 之前返回数组,甚至在任何上传完成之前。
解决方案是(一如既往地涉及异步操作)等待所有操作在 resolving/returning 之前完成。您可以使用 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);
}
我正在创建一个博客网站,并且正在编写按顺序执行以下操作的代码:
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);
}
});
}
这是上传功能代码的一部分,它将所有相关数据上传到数据库,包括上面函数中承诺返回的 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 数组。
这是我在调试时发现的:
-照片存储没有任何问题。
- 为每个文件下载url,在执行代码中如预期成功返回urlarray。
可能出了什么问题?我在这里迷路了。非常欢迎任何建议。
非常感谢!
每次调用 storageRef.put(...)
它都会启动一个异步操作。现在你的 `` 不会等待这些异步操作完成,而是 returns URLS 的列表在它被填充之前。
查看此内容的最简单方法是在您的代码中添加一些简单的日志记录:
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);
}
});
}
当您 运行 此代码时,输出将如下所示:
Starting to put file...
Starting to put file...
Starting to put file...
Resolving with 0 download URLs
Upload done, getting download URL...
Download URL gotten, adding to array...
Upload done, getting download URL...
Download URL gotten, adding to array...
Upload done, getting download URL...
Download URL gotten, adding to array...
这当然不是您想要的顺序,因为您在向数组添加任何下载 URL 之前返回数组,甚至在任何上传完成之前。
解决方案是(一如既往地涉及异步操作)等待所有操作在 resolving/returning 之前完成。您可以使用 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);
}