Struggling to get the data from useDocument to display with vue.js and Firestore

907 Views Asked by At

I'm trying to get a single record from Firestore to display in Vue.js. I'm using VueFire and the guide here.

<script setup>    
import { initializeApp } from 'firebase/app'
import { getFirestore , doc } from "firebase/firestore"; 
import { useDocument } from 'vuefire'

const firebaseConfig = {...};

// Initialize Firebase
const firebaseApp = initializeApp(firebaseConfig);
const analytics = getAnalytics(firebaseApp);
const db = getFirestore(firebaseApp);

const place  = useDocument(doc(db, "data", "key"));
console.log(place)
</script>

<template>
  {{ place.title }}
</template>

The data logged is RefImpl {__v_isShallow: false, dep: undefined, __v_isRef: true, _rawValue : {title: 'I am a title', however when it gets to the template there is an error

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'title')

2

There are 2 best solutions below

0
On

Maybe try this.

...
const { data: place, pending } = useDocument(doc(db, "data", "key"));
</script>

<template>
  <h1>Place</h1>
  <template v-if="!pending">{{ place.title }}</template>
</template>

I'm just following what they the author of VueFire has posted here: https://github.com/vuejs/vuefire/blob/df3c235f226d4e4c821391bcce74a1c3a6134406/packages/nuxt/playground/pages/firestore-useDocument.vue

You can use the pending property to show the place once it has loaded.

You can also read about Subscription State here where they talk about destructuring. https://v3.vuefire.vuejs.org/guide/realtime-data.html#subscription-state

0
On

If anyone finds this because they need the data from useDocument() asynchronously, you can do something similar, based on Kyle's suggestion above (the Github post by the vueFire author):

const { data: place, promise } = useDocument(doc(db, 'data', 'key'))
promise.value.then((place) => {
  // do something with place like console.table(place)
})

Even if you don't want to listen for changes, you still have to use the "subscription" method to get the data asynchronously. async/await doesn't work. This needs to be a lot clearer in the documentation IMHO.