Floran
Floran

Reputation: 57

Get storage image url as a string with VueFire

I'm a beginner with VueJS and I'm facing my first big blocking issue as I'm trying to get an image URL from Firebase Storage, using the VueFire plugin. Here's what I do:

export const usePlaces = defineStore('places', {
  state: (): PlaceState => ({
    places: useCollection(placesRef),
  }),
  getters: {
    getPlace(state: PlaceState) {
      return (placeId: string) => state.places.find((p) => p.id === placeId)
    },
  },
  actions: {
    fetchImagesURL(placeId: string): string[] {
      const place = this.getPlace(placeId)
      if (place) {
        const imagesUrlArray: string[] = []
        place.images.forEach((imgFilename) => {
          const imageRef = storageRef(storage, `/places/${imgFilename}`)
          const { url } = useStorageFileUrl(imageRef)
          const urlRef = url
          imagesUrlArray.push(url)
        })
        return imagesUrlArray
      }
      return []
    },
  },
})

<template>
    <pre>debug : {{ placeImagesUrl[0] }}</pre>
    <img :src="placeImagesUrl[0]" alt="Large image" />
</template>

<script setup>
import Tag from '@/shared/components/Tag.vue'
import Icon from '@/shared/components/Icon.vue'
import { useRoute } from 'vue-router'
import { usePlaces } from '@/shared/store/placeStore'
import PlaceReview from './PlaceReview.vue'
import { onMounted, computed, ref } from 'vue'

const route = useRoute()
const placeStore = usePlaces()
const place = placeStore.getPlace(route.params.placeId)
const placeImagesUrl = ref([])

onMounted(async () => {
  placeImagesUrl.value = placeStore.fetchImagesURL(place.id)
})
</script>

But what happens is that my src contains [object Object]. That is weird to me because when I call the same thing from the I get the URL expected, as a string. I'm not able to understand what I'm doing wrong but I believe it has something to do with reactivity.

Upvotes: 0

Views: 39

Answers (2)

Floran
Floran

Reputation: 57

Given the complexity I decided to opt for a simpler approach: if you don't need to get just the filename (you just want to display the image, no specific action), you can directly put the download url of the storage directly. It's not very readable from Firebase side but at least you can easily use it in a <img> tag as you just have to call the key from your store (place.images[0]) for instance in my case.

Upvotes: 0

Smileek
Smileek

Reputation: 2797

https://vuefire.vuejs.org/api/modules/vuefire.html#useStorageFileUrl says that url that you get is a ref object. So, probably the only change you'll need is this:

imagesUrlArray.push(url.value)

To make it easier for yourself in the future, use console.log(placeImagesUrl.value) or the Vue browser plugin to check the actual object data instead of its stringified version ([Object object]).

Upvotes: 0

Related Questions