0

I am getting the image location from firestore and would like to show the image using v-bind:src. You can find my code below:

<b-avatar v-bind:src = "profilepic" class="mr-5" size="8em"></b-avatar>

my methods can be found below:

export default {
    data() {
        return {
            uid: "",
            profilepic: "",
        }
    },
    methods: {
        getprofilepic() {
            fb.storage().ref('users/' + this.uid + '/profile.jpg').getDownloadURL().then(imgURL  => {
                this.profilepic = imgURL;
                alert(this.profilepic); // shows the correct path
            })
        },
    }


    created() {
        this.uid = fb.auth().currentUser.uid;
        this.getprofilepic();
    }

}

I am confident that this.profilepic is storing the correct path as if i were to manually type in the path, it will show. I am suspecting that the page loaded before path could be retrieve from firestore. How can i work around this? Thank you in advance.

I have tried hardcoding the path directly to the data and it works fine. The code can be found below:

 data() {
        return {
            uid: "",
            profilepic: "*my firebase storage path*",
        }
    },

With that im not really sure why isnt it still showing

Samuel
  • 225
  • 3
  • 11

3 Answers3

0

Try waiting for the uuid to get retrieved:

<template>
  <img height="200" v-bind:src = "profilepic" />
</template>

<script>
export default {
  data() {
    return {
      uuid: undefined,
      profilepic: undefined
    }
  },
  methods: {
    getprofilepic() {
      fb.storage().ref('users/' + this.uid + '/profile.jpg').getDownloadURL()
        .then(imgURL  => {
        this.profilepic = imgURL;
      })
    },
    getuuid(){
      return new Promise((resolve, reject) => {
        var user = fb.auth().currentUser;
        if(user == null) reject()
        if (user) resolve(user.uid)
      })
    }
  },
  created() {
    this.getuuid()
      .then(uuid => this.uuid = uuid)
      .then(() => {
      this.getprofilepic();
    })
  }
};
</script>

As you can see in this example, it does not matter how long it takes for the URL to load: Vue SFC Playground

tauzN
  • 5,162
  • 2
  • 16
  • 21
  • hmm i tried using your method but it doenst work. i think its more about waiting for the firebase storage path to be retrieve before loading the screen. is there a way to do that? thanks! – Samuel Apr 07 '21 at 05:44
  • That should not be the problem. But you can try to bind `v-if` to `profilepic`on `` like this: `v-if="profilepic.length > 0"` – tauzN Apr 07 '21 at 08:27
  • I have updated the answer with an example where it takes 1 second for an image to load with no problem. The img-tag updates when the data changes. – tauzN Apr 07 '21 at 08:32
0

In the script below the template tags, you need to make sure to include the image, and of course, instead of putting my path, put your image's path!

<script>
    export default {
        data() {
            return {
                files: {
                    my_pic: require('/src/assets/img/avatars/logo.png')
                }
            };
        },
       }
     };
 </script>

Then in your and where you want to put your image, you need to put it in this format

 <img :src="files.my_pic">

Let me know if this helps or if you want me to expand more.

Maria
  • 11
  • 1
  • Hi @Maria, thank you so much for help. However, I am still unable to solve it, although i believe your solution might be correct. As i am using firestore to retrieve the path of the image, I had to do this instead but it still didnt work: – Samuel Apr 07 '21 at 05:53
0

When Vue Loader compiles the <template> blocks in SFCs, it also converts any encountered asset URLs into webpack module requests.

For example, the following template snippet:

<img src="../image.png">

will be compiled into:

createElement('img', {
 attrs: {
  src: require('../image.png') // this is now a module request
 }
})

By default the following tag/attribute combinations are transformed, and can be configured using the transformAssetUrls option.

{
  video: ['src', 'poster'],
  source: 'src',
  img: 'src',
  image: ['xlink:href', 'href'],
  use: ['xlink:href', 'href']
}

Step 1: Create vue.config.js

 module.exports = {
  productionSourceMap: false,
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options['transformAssetUrls'] = {
          video: ['src', 'poster'],
          source: 'src',
          img: 'src',
          image: 'xlink:href',
          'b-avatar': 'src',
          'b-img': 'src',
          'b-img-lazy': ['src', 'blank-src'],
          'b-card': 'img-src',
          'b-card-img': 'src',
          'b-card-img-lazy': ['src', 'blank-src'],
          'b-carousel-slide': 'img-src',
          'b-embed': 'src'
        }
        return options
      })
  }
}

Step 2: Inside main.js import vue.config

import '../vue.config'

Step 3: Create your html template

<template>
  <b-avatar :src="profilepic" class="mr-5" size="8em"></b-avatar>
</template>
<script>
  import { BAvatar } from 'bootstrap-vue'
  export default {
    name: 'bootstrap-image-avatar',
    components: {
      'b-avatar': BAvatar
    },
    data() {
      return {
        uid: "",
        profilepic: "",
      }
    },
    methods: {
      getprofilepic() {
        fb.storage().ref('users/' + this.uid + '/profile.jpg').getDownloadURL().then(imgURL  => {
          this.profilepic = imgURL;
          alert(this.profilepic); // shows the correct path
        })
      },
    }
    created() {
      this.uid = fb.auth().currentUser.uid;
      this.getprofilepic();
    }
  }
</script>
Jebasuthan
  • 5,538
  • 6
  • 35
  • 55
  • @Samuel Hopefully it will helps you. Try and let me know. – Jebasuthan Apr 07 '21 at 17:00
  • Hi Jebasuthan, thank you for the very detailed explanation. I have tried your solution but it still doesnt work. I have tried hardcoding the path directly into data.. for e.g profilepic: "firebase storage path" and use v-bind:src = "profilepic" and it works.. So i believe the problem is more towards the storage? im not really sure too. – Samuel Apr 07 '21 at 17:22
  • Hi @Jebasuthan , I have found the error but not really sure how to work around this. I have post an updated issue for clarity. The link can be found here: https://stackoverflow.com/questions/66998550/unable-to-assign-to-data-var-in-vuejs-after-firestore-storage?noredirect=1#comment118427999_66998550 – Samuel Apr 08 '21 at 06:49