上传到 AngularFireStore 后无法从 getDownloadUrl() 内部访问变量

unable to access variable from inside getDownloadUrl() after uploading to AngularFireStore

我已经成功将图像上传到我的 firebase 存储中,但我还想检索下载 URL 并将其添加到我的 firestore 数据库中。控制台日志记录“URL” return 是我想要的 link。但是我在使用它时遇到了问题。

我试过了 this.profileImage = URL 但是控制台总是return我报错Cannot set 属性 'profileImage' of undefined。 我通过在构造函数上方写profileImage来定义它。

我也试过将整个 firestore 功能放在里面,但控制台将 return 无法读取未定义的 属性 'firestore'。 我正在使用 Ionic 5。

imageRef.getDownloadURL().then((url)=> {
    this.firestore.collection('users').doc(this.user.id).update({image.url})
       console.log("this is my image" + url)
})

这是我目前拥有的

uploadImage(imageURI) {
    return new Promise<any>((resolve, reject) => {
      let storageRef = firebase.storage().ref();
      const imageRef = storageRef.child('image').child(this.createFileName());
      this.encodeImageUri(imageURI, function (image64) {
        imageRef.putString(image64, 'data_url')
          .then(function (snapshot) {
            console.log(snapshot)
            resolve(snapshot.downloadURL)
            imageRef.getDownloadURL().then((url)=> {
              this.profileImage = url
              console.log(this.profileImage)
              console.log("this is my image" + url)
            })
          }, err => {
            reject(err);
          })
      })
    })
  }
encodeImageUri(imageUri, callback) {
    var c = document.createElement('canvas');
    var ctx = c.getContext("2d");
    var img = new Image();
    img.onload = function () {
      var aux: any = this;
      c.width = aux.width;
      c.height = aux.height;
      ctx.drawImage(img, 0, 0);
      var dataURL = c.toDataURL("image/jpeg");
      callback(dataURL);
    };
    img.src = imageUri;
  };

如果你使用的是“普通”函数而不是箭头函数,你将失去“this context”。

箭头函数和“普通”函数的区别:

uploadImage(imageURI) {
    return new Promise<any>((resolve, reject) => {
      let storageRef = firebase.storage().ref();
      const imageRef = storageRef.child('image').child(this.createFileName());
        // replaced with an arrow function
      this.encodeImageUri(imageURI, (image64) => {
        imageRef.putString(image64, 'data_url')
             // replaced with an arrow function
          .then((snapshot) => {
            console.log(snapshot)
            imageRef.getDownloadURL().then((url)=> {
              this.profileImage = url
              console.log(this.profileImage)
              console.log("this is my image" + url)
                // call the resolve method after all async tasks are complteded.
              resolve(snapshot.downloadURL)
            })
          }, err => {
            reject(err);
          })
      })
    })
  }

此外,我建议使用 await/async 而不是 then/catch。

async uploadImage(imageURI) {
  const storageRef = firebase.storage().ref();
  const imageRef = storageRef.child('image').child(this.createFileName());
  const image64 = await this.encodeImageUri(imageURI);
  const snapshot = await imageRef.putString(image64, 'data_url');
  const url = imageRef.getDownloadURL();
  this.profileImage = url;
  return snapshot.downloadURL;
}