如何将Firebase上传图像的图像下载URL转换为base64

时间:2019-08-21 15:57:19

标签: javascript firebase vue.js google-cloud-firestore firebase-storage

我正在尝试在Vue.js Firebase应用程序中实现图像上传器组件。我将上传器设置为首先使用.put()将图像放入Firebase存储中。然后使用.getDownloadURL()检索downloadURL,然后将其保存到数据库以便在整个应用程序中呈现:this.imageUrl = downloadURL。在上传了多个图像之后,我注意到数据库中存储的某些图像的downloadURL显示为base64字符串,而其他图像的downloadURL显示为以https://firebasestorage.googleapis.com/...开头的常规URL。我希望downloadURL作为一个或另一个在数据库中一致显示。哪种格式更适合存储在数据库中?我如何设置下面的代码以一致地解释一个或另一个?我的代码如下。谢谢!

        var storageRef = firebase.storage().ref()
        var mountainsRef = storageRef.child(`images/${this.imageName}`)
        mountainsRef.put(this.imageFile).then(snapshot => {
          snapshot.ref.getDownloadURL().then(downloadURL => {
            this.imageUrl = downloadURL
          })
        })

完整组件

<template>
  <div class="sign-up">
    <v-container fluid fill-height>
     <v-layout align-center justify-center>
       <v-flex xs12 sm8 md4>
         <v-card class="elevation-8">
           <v-toolbar dark color="primary">
             <v-toolbar-title>Let's create a new account!</v-toolbar-title>
           </v-toolbar>
           <v-card-text>
             <v-form>
               <v-text-field prepend-icon="person" v-model="email" name="email" label="Email" type="text"></v-text-field>
               <v-text-field prepend-icon="lock" v-model="password" name="password" label="Password" id="password" type="password"></v-text-field>
               <v-text-field prepend-icon="lock" v-model="name" name="name" label="Name" id="name" type="text"></v-text-field>

               <v-layout align-center justify-center>
                 <v-flex xs12 sm8 md4>
                   <img :src="imageUrl" height="150" v-if="imageUrl" />
                   <v-text-field label="Select Image" @click="pickFile" v-model="imageName"></v-text-field>
                   <input type="file" style="display: none" ref="image" accept="image/*" @change="onFilePicked"/>
                 </v-flex>
               </v-layout>

             </v-form>
           </v-card-text>
           <v-card-actions>
             <v-container>
               <v-btn @click="signUp" color="info">Sign Up</v-btn>
             </v-container>
           </v-card-actions>
         </v-card>
         <v-card-text>Return to <router-link to="/login"><strong>login</strong></router-link>.</v-card-text>
       </v-flex>
     </v-layout>
   </v-container>
  </div>
</template>
<script>
import slugify from 'slugify'
import firebase from 'firebase'
import db from '@/firebase/init'
export default {
  name: 'signUp',
  data () {
    return {
      email: '',
      password: '',
      name: '',
      slug: null,
      imageName: null,
      imageUrl: '',
      downloadUrl: '',
      imageFile: null
    }
  },
  methods: {
    signUp () {
      if (this.name && this.email && this.password) {
        this.slug = slugify(this.name, {
          replacement: '-',
          remove: /[$*_+~,()'"!\-:@]/g,
          lower: true
        })
        // UPLOAD
        var storageRef = firebase.storage().ref()
        var mountainsRef = storageRef.child(`images/${this.imageName}`)
        mountainsRef.put(this.imageFile).then(snapshot => {
          snapshot.ref.getDownloadURL().then(downloadURL => {
            this.imageUrl = downloadURL
          })
        })
        // end UPLOAD
        let ref = db.collection('users').doc(this.slug)
        ref.get().then(doc => {
          if (doc.exists) {
            this.feedback = 'This alias already exists'
          } else {
            firebase.auth().createUserWithEmailAndPassword(this.email, this.password)
              .then(cred => {
                ref.set({
                  name: this.name,
                  email: this.email,
                  user_id: cred.user.uid,
                  imageUrl: this.imageUrl,
                  downloadUrl: this.downloadUrl
                })
              }).then(() => {
                this.$router.push({ name: 'Dashboard' })
              })
              .catch(err => {
                this.feedback = err.message
              })
            this.feedback = 'This alias is free to use'
          }
        })
      } else {
        this.feedback = 'You must enter all fields'
      }
    },
    pickFile () {
      this.$refs.image.click()
    },
    onFilePicked (e) {
      const files = e.target.files
      if (files[0] !== undefined) {
        this.imageName = files[0].name
        if (this.imageName.lastIndexOf('.') <= 0) {
          return
        }
        const fr = new FileReader()
        fr.readAsDataURL(files[0])
        fr.addEventListener('load', () => {
          this.imageUrl = fr.result
          this.imageFile = files[0]
        })
      } else {
        this.imageName = ''
        this.imageFile = ''
        this.imageUrl = ''
      }
    }
  }
}
</script>

1 个答案:

答案 0 :(得分:1)

为什么“存储在数据库中的某些图像的downloadURL显示为base64字符串,而其他图像的downloadURL显示为常规URL”的原因是,您在上传之前将<div id="banner-message"> <button>A</button> <button>B</button> </div> $(".btn").click(()=>{ let extraprice = this.attr("data-price"); let total = $("#total-price").text(); total + extraprice; }) 设置为用户零件已准备好..因此您最终保存了imageUrl,它最初设置为this.imageUrl FileReader

相反,您应该等到从.result获得正确的downloadURL且只有firebase.storage设置用户then为止。

imageUrl