异步上传多个文件并在 firebase 存储问题中获取它们的 url

时间:2021-03-03 20:46:39

标签: javascript vue.js asynchronous firebase-storage

所以基本上我的问题在于标题。我有一张图片,而不是我有多个文件上传输入。我想将它们添加到 Firebase 存储中。我这样做了,它工作正常,当我想获取这些下载 url 时问题就出现了。在这种情况下,为多个文件获取 url 工作正常,当我想将它传递给这个单独的图像文件时,它最终会为空。顺便说一下,我正在使用 vue.js。所以这是我使用的方法代码,所有输入都很好。

methods:{
   async uploadImageFile() {
     var slugify = require('slugify')
     let imageName = this.$refs.image.files[0].name.split(".")[0]
     let ext = this.$refs.image.files[0]['name'].split(".")[1]
     this.blog.image = slugify(imageName)
     const {canvas} = this.$refs.cropper.getResult();
     if (canvas) {
       canvas.toBlob( blob => {
         let uploadTask = storageRef.child('blogs/' + this.blog.image +"-"+ moment().unix()+ "." +ext)
         try {
           uploadTask.put(blob)
           let downloadURL = uploadTask.getDownloadURL()
           this.blog.imageUrl = downloadURL
         }
         catch (error){
           console.log(error)
         }
       });
     }
   },
   save() {
     let slugify = require("slugify")
     this.blog.slug = slugify(this.blog.title)
     this.blog.user = usersCollection.doc(this.$store.state.userProfile.uid)
     this.blog.active = false
     this.blog.created = firebase.firestore.Timestamp.fromDate(new Date())
     blogsCollection.add(this.blog).then(() => {
       router.push('/admin/blogs');
     }).catch((error) => {
       console.error("Error adding document: ", error);
     });
   },
   async saveFiles(){
     await this.uploadImageFile()
     for(const fileIndex in this.files){
       let timestamp = new Date()
       let fileObject = this.files[fileIndex]
       let fileNameName = fileObject.name
       let ext = fileObject.name.split(".")[1]
       try {
         let uploadTask = storageRef.child('blogs/' + fileNameName.split(".")[0] + "-" + timestamp.getTime().toString() + "." + ext)
         await uploadTask.put(fileObject)
         let downloadURL = await uploadTask.getDownloadURL()
         this.blog.files.push({fileName:fileNameName,
           fileURL:downloadURL})
       } catch (error){
         console.log(error)
       }
     }
     this.save()
   }
}

我为 saveFiles() 函数设置了@click 方法..

2 个答案:

答案 0 :(得分:0)

假设您将 firebase 导入为 fb

尝试这样的事情:

let uploadTask = storageRef.child('blogs/' + fileNameName.split(".")[0] + "-" + timestamp.getTime().toString() + "." + ext)
await uploadTask.put(fileObject)    
fb.UploadTaskSnapshot taskSnapshot = await uploadTask.future;
Uri downloadUrl = await taskSnapshot.ref.getDownloadURL();
url1 = downloadUrl.toString();

url1 将是带有下载 url 的字符串

答案 1 :(得分:0)

好的,所以我在发布问题 2 小时后想通了,但忘记检查任何可能的答案。所以这里的交易是这里发生了大量的异步函数。所以对我来说最好的事情是创建那种功能链。首先做save​​Files,然后uploadImage,然后Save。一种可能的解决方法是在 uploadImage 函数中,我选择裁剪器的内容并将其转换为 blob,以便我可以将其上传到存储,在那里我可以调用 async 并等待 blob 完成上传,以便我可以相应地获取图像的 url。我将发布经过编辑的代码,该代码可以运行并执行我想要的操作。

    async saveFiles(){
      if(!this.files){
        this.uploadImageFile()
        return
      }else {
        let slugify = require("slugify")
        for (const fileIndex in this.files) {
          let timestamp = new Date()
          let fileObject = this.files[fileIndex]
          let ext = fileObject.name.split(".")[1]
          let fileNameName = slugify(fileObject.name.split(".")[0]) + "-" + 
    timestamp.getTime().toString() + "." + ext
          try {
            let uploadTask = storageRef.child('blogs/' + fileNameName)
            await uploadTask.put(fileObject)
            let downloadURL = await uploadTask.getDownloadURL()
            this.blog.files.push({
              fileName: fileNameName,
              fileURL: downloadURL
            })
          } catch (error) {
            console.log(error)
          }
        }
        //here we call the uploadImageFile
        this.uploadImageFile() 
      }
    },
    //then we have the uploadImageFile func
    uploadImageFile() {
      var slugify = require('slugify')
      let imageName = this.$refs.image.files[0].name.split(".")[0]
      let ext = this.$refs.image.files[0]['name'].split(".")[1]
      this.blog.image = slugify(imageName)+"-"+moment().unix() + "." + ext
      const {canvas} = this.$refs.cropper.getResult();
      if (canvas) {
        canvas.toBlob(blob => {
          let uploadTask = storageRef.child('blogs/' + this.blog.image ).put(blob)
          uploadTask.on('state_changed',
              (snapshot) => {
                switch (snapshot.state) {
                  case firebase.storage.TaskState.PAUSED: // or 'paused'
                    break;
                  case firebase.storage.TaskState.RUNNING: // or 'running'
                    break;
                }
              },
              (error) => {
                console.log(error);
              },
              () => {
                this.save(uploadTask)
              }
          );
        }, 'image/jpeg');
      }
      this.save()
    },
    //then we have the save
    save(uploadTask){
      let task = uploadTask.snapshot.ref.getDownloadURL();
      task.then((url)=> {
        this.blog.imageUrl = url
        let slugify = require("slugify")
        this.blog.slug = slugify(this.blog.title)
        this.blog.user = usersCollection.doc(this.$store.state.userProfile.uid)
        this.blog.active = false
        this.blog.created = firebase.firestore.Timestamp.fromDate(new Date())
        this.blog.type = this.selected
        blogsCollection.add(this.blog).then(() => {
          router.push('/admin/blogs');
        }).catch((error) => {
          console.error("Error adding document: ", error);
        });
      })
    }

现在这个功能块正在做我想要的。上传文件,然后获取该文件的下载 url。之前的代码正在执行并且没有等待 url,因为同时发生了很多事情,并且它没有等待 url 响应。干杯!