Как загрузить более одного изображения в Firebase и загрузить URL-адрес - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь загрузить набор изображений в Firebase. Сама закачка работает, картинки добавляются. Однако я хотел бы получить URL-адрес изображений.

Я решил, что могу сохранить их в массиве, но что бы я ни делал, в URL-адресе сохраняется только одно изображение.

Я хочу A, загрузить набор изображений (максимум 3) или B, загрузить только одно изображение. Поэтому я устанавливаю целевые файлы в состояние и использую это состояние, чтобы проверить, есть ли одно или несколько изображений. Затем я oop выполняю загрузку x количество раз и отправляю sh ответ в ... URL. Независимо от того, что я делаю, у меня остается только один URL-адрес изображения в firebase.

Попытаюсь уточнить немного больше: я хочу загрузить до трех изображений в Firebase (это работает, изображения загружаются в ведро изображений.

Я хочу получить URL-адрес загрузки изображений (я хочу использовать URL-адрес изображения в другом компоненте. По сути, я хочу создать галерею изображений или карусель изображений с изображениями.

По сути, получение URL-адреса изображения из Firebase и отображение изображений.

Это то, что отображается в firebase: https://imgur.com/a/LOBgVK1

Это console.log (url): https://imgur.com/hZrAl0P

 const AddCountryForm = () => {

  const [url, setUrl] = useState([]);
  const [fileArray, setFileArray] = useState([]);



  function onSubmit(e) {
    firebase
      .firestore()
      .collection(continent)
      .doc(revName)
      .set({
        url,

      })
      .then(() => {
        setUrl("");

      });
  }


  const handleChange = (e) => {
    setFileArray(e.target.files);
  };


  const handleUpload = (e) => {
    e.preventDefault();


    if (fileArray.length > 1) {
      for (let i = 0; i < fileArray.length; i++) {
        const uploadTask = storage.ref(`images/${fileArray[i].name}`).put(fileArray[i]);

        uploadTask.on(
          "state_changed",

          () => {
            storage
              .ref("images")
              .child(fileArray[i].name)
              .getDownloadURL()
              .then(res => {
                setUrl([...url, res]); 
              });
          }

        );
      }
    }
    if (fileArray.length === 1) {
      const uploadTask = storage.ref(`images/${fileArray[0].name}`).put(fileArray[0]);
      uploadTask.on(
        "state_changed",

        () => {
          storage
            .ref("images")
            .child(fileArray[0].name)
            .getDownloadURL()
            .then(res => {
              setUrl([res]);
            });
        }
      );
    }

  };

return (
    <form onSubmit={handleSubmit(onSubmit)}>
          <div>
        <input type="file" onChange={handleChange} required multiple />
        <button onClick={handleUpload}> Upload</button>
      </div>

      <input type="submit"></input>
    </form>
  );
};
export default AddCountryForm;

1 Ответ

2 голосов
/ 26 мая 2020

Вы хотите выполнить несколько асинхронных вызовов put() и getDownloadURL() к Firebase Storage параллельно.

Необходимо использовать Promise.all(), поскольку put() возвращает UploadTask (который «ведет себя как Promise и разрешается с данными своего моментального снимка после завершения загрузки»), а getDownloadURL() возвращает Promise.

Следовательно, следующее должно помочь (не проверено):

  if (fileArray.length > 1) {
    const uploadPromises = [];
    for (let i = 0; i < fileArray.length; i++) {
      uploadPromises.push(
        storage.ref(`images/${fileArray[i].name}`).put(fileArray[i])
      );
    }
    Promise.all(uploadPromises)
      .then((uploadTaskSnapshots) => {
        const urlPromises = [];

        uploadTaskSnapshots.forEach((uploadTaskSnapshot) => {
          urlPromises.push(uploadTaskSnapshot.ref.getDownloadURL());
        });

        return Promise.all(urlPromises);
      })
      .then((urls) => {
        setUrl(urls);
      });
  }
...