简体   繁体   English

将一组图像上传到 Firebase 存储

[英]Uploading an array of images to firebase storage

I am trying to upload an array of images to firebase storage.我正在尝试将一组图像上传到 firebase 存储。 I have written a function for single image upload and it works perfectly, but i cannot seem to wrap my head around how I can implement image array upload.我已经为单张图像上传编写了一个函数,它运行良好,但我似乎无法理解如何实现图像数组上传。 Can someone kindly point me in the right direction.有人可以指出我正确的方向。 Below is my sample, and I have kept only the relevant part以下是我的样本,我只保留了相关部分

        uploadAsync = async uri => {
          const user = Firebase.auth.currentUser.uid;
          const path = `users/${user}/images/${Math.round(
                  Math.random() * 1000000000
              )}.jpg`;

          return new Promise(async (res, rej) => {
            const response = await fetch(uri);
            const file = await response.blob();

            const upload = Firebase.storage().ref(path).put(file);

            upload.on(
              'state_changed',
              snapshot => {},
              err => {
                rej(err);
              },
              async () => {
                const url = await upload.snapshot.ref.getDownloadURL();
                res(url);
              }
            );
          });
        };

        updateImage = async ({ image }) => {
          const user = Firebase.auth.currentUser.uid;
          for (let i = 0; i < image.length; i++) {
            const file = image[i].image;
            const remoteUri = await this.uploadAsync(file);
            const firestoreRef = firebase.firestore().collection('Images').doc(user);
            firestoreRef.set({
              image: [remoteUri]
            });
          }
        }

You can use Promise.all() .您可以使用Promise.all() As explained in the doc:如文档中所述:

The Promise.all() method returns a single Promise that fulfills when all of the promises passed as an iterable have been fulfilled Promise.all()方法返回一个 Promise,当作为可迭代对象传递的所有 Promise 都已完成时,该 Promise 会完成

..... .....

The returned promise is fulfilled with an array containing all the values of the iterable passed as argument (also non-promise values).返回的promise 由一个数组实现,该数组包含作为参数传递的iterable 的所有值(也是非promise 值)。

Since your updateImage() function is an async one, you can pass to Promise.all() an array of "calls" to this function (the "iterable" mentionned above) that you generate based on imageArray which is an array of image Objects (the exact same image object you pass to the updateImage() function).由于您的updateImage()函数是一个异步函数,您可以将基于imageArray生成的该函数的“调用”数组(上面提到的“可迭代” Promise.all()传递给Promise.all()数组,该数组是一个image对象数组(您传递给updateImage()函数的完全相同的image对象)。

So you could do as follows:所以你可以这样做:

const updateImageArray = async (imageArray) => {
  return Promise.all(imageArray.map(item => updateImage(item)));
}

const imageArray = [....];

updateImageArray(imageArray).then(urls => {
    urls.forEach(element => {
        console.log(element);
    });
})

Or in an async function:或者在异步函数中:

const urlsArray = await updateImageArray(imageArray);

Basically the issue here is that you need to upload every image on its own.基本上这里的问题是您需要自己上传每个图像。 A "bundle" upload or similar does not exist.不存在“捆绑”上传或类似内容。

The normal approach正常方法

The basic approach to such a propblem would be looping over the array (here array of images imgArr ) and upload each item individually.这种问题的基本方法是遍历数组(这里是图像数组imgArr )并单独上传每个项目。
Such a function can look like this:这样的函数看起来像这样:

for (i = 0; i < imgArr.length; i++) {
    this.updateImage(imgArr[i]);
}

or with the forEach method:或使用 forEach 方法:

imgArr.forEach((img) => {
    this.updateImage(img);
}

Remember : The function this.updateImage is provided in the original code.切记:原代码中提供了this.updateImage函数。

Im the case of an asynchronous function like an upload, a fetch of data or other this approach does NOT work.对于异步功能,如上传、数据获取或其他这种方法不起作用。 This is caused by the implementation of JS and fact, that the operation inside the for(Each) loop is not possible to await.这是由 JS 的实现造成的,事实上,for(Each) 循环内的操作是不可能等待的。

The solution comes with the asyncForEach .解决方案随asyncForEach 一起提供 The asyncForEach function executes the asynchronous task (uploading the image) and waits for it to be done. asyncForEach 函数执行异步任务(上传图像)并等待它完成。

The implementation works like this (details below):实现的工作原理如下(详细信息如下):

  1. Add the function asyncForEach to your code将函数 asyncForEach 添加到您的代码中
  2. call the function asyncForEach when uploading the array上传数组时调用函数 asyncForEach

Implementation执行
To implement the asynchromous upload do the following:要实现异步上传,请执行以下操作:
add the following function somewhere in the upper part of your .js file..js文件的上部某处添加以下函数。

// implementation of asynchonous forEach   
// array: array of items to process
// callback: the asynchonous function to process the items 
async asyncForEach(array, callback) {
    for (let index = 0; index < array.length; index++) {
        await callback(array[index], index, array);
    }
}

to then call the newly implemented function call it with the following lines of code然后调用新实现的函数,使用以下代码行调用它
( Note : the variable 'imgArr' represents the array of images to upload): 注意:变量 'imgArr' 表示要上传的图像数组):

// create a function 'uploadArray' in which the asyncForEach is called. 
const uploadArray= async () => {
    await this.asyncForEach(imgArr, async (img) => {
        await this.updateImage(img);
    };
/* execute the function. The code following this function call will be 
stalled until the images are either uploaded or failed with error 
(implement error handling in the this.updateImage function
await uploadArray()

Ressources资源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM