Как я могу вернуть URL загрузки изображения, загруженного в хранилище Firebase? - PullRequest
0 голосов
/ 03 ноября 2019

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

Вот мой код:

uploadImage = async (uri, imageName) => {
    const response = await fetch(uri);
    const blob = await response.blob();

    firebase.storage().ref().child(imageName).put(blob)
      .then(snap => {
        return snap.ref.getDownloadURL();
      })
      .then(downloadURL => {
        return downloadURL;
      })
      .catch(error => {
        console.log(`An error occurred while uploading the file.\n\n${error}`);
      });
  }

Изображение загружается в хранилище Firebase просто отлично. В данный момент это просто показывает это, когда я пытаюсь записать URL загруженного изображения в базу данных: https://ibb.co/WHHHxBY

Вот блок кода, в котором я создаю запись пользователя:

  firebase
    .auth()
    .createUserWithEmailAndPassword(this.state.email, this.state.password)
    .then(userCredentials => {
      let imageUrl = '';

      let db = firebase.database().ref('users/' + userCredentials.user.uid);

      if (this.state.image) {
        imageUrl = this.uploadImage(this.state.image.uri, `images/user-${userCredentials.user.uid}`);
      }

      db.set({
        email: this.state.email,
        imageUrl: imageUrl,
        username: this.state.username
      });

      return userCredentials.user.updateProfile({
        displayName: this.state.username
      });
    })
    .catch(error => this.setState({ errorMessage: error.message }));

1 Ответ

1 голос
/ 03 ноября 2019

В вашей функции uploadImage вы объединяете обещания, но не возвращаете цепочку. Вы должны адаптировать его следующим образом:

uploadImage = async (uri, imageName) => {
    const response = await fetch(uri);
    const blob = await response.blob();

    return firebase.storage().ref().child(imageName).put(blob)  // <-- Here return the chain
      .then(snap => {
        return snap.ref.getDownloadURL();
      })
      .then(downloadURL => {
        return downloadURL;
      })
      .catch(error => {
        console.log(`An error occurred while uploading the file.\n\n${error}`);
      });
  }

Однако вы можете преобразовать этот код в async/await «стиль», следующим образом:

uploadImage = async (uri, imageName) => {

    try {
        const response = await fetch(uri);
        const blob = await response.blob();

        const snap = await firebase.storage().ref().child(imageName).put(blob);

        const downloadURL = await snap.ref.getDownloadURL();

        return downloadURL;

    } catch (e) {
        console.error(e);
        throw e;
    }

}

Тогда, поскольку это uploadImageФункция асинхронная, вы должны адаптировать ее так, как вы ее называете. Я предлагаю изменить другую часть вашего кода следующим образом:

try {
     const userCredentials = await firebase
        .auth()
        .createUserWithEmailAndPassword(this.state.email, this.state.password);

     let imageUrl = '';

     const db = firebase.database().ref('users/' + userCredentials.user.uid);

     if (this.state.image) {

        imageUrl = await this.uploadImage(this.state.image.uri, `images/user-${userCredentials.user.uid}`);

        await db.set({
            email: this.state.email,
            imageUrl: imageUrl,
            username: this.state.username
          });


          return userCredentials.user.updateProfile({
            displayName: this.state.username
          });

     }
     //You should probably manage the else case

} catch (e) {
     this.setState({ errorMessage: e.message })
}
...