2

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')

kissu
  • 40,416
  • 14
  • 65
  • 133
Richard
  • 61
  • 1
  • 3
  • 1
    this answers may be the solution you're after, https://stackoverflow.com/questions/46128557/any-easier-way-to-access-nested-object-properties-in-vue-template – mzm Dec 25 '22 at 22:31
  • Does this answer your question? [firebase - Uncaught TypeError: Cannot read properties of undefined (reading 'options')](https://stackoverflow.com/questions/72257173/firebase-uncaught-typeerror-cannot-read-properties-of-undefined-reading-opt) – Robert G Dec 26 '22 at 18:01

2 Answers2

2

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

Kyle Buchanan
  • 193
  • 1
  • 10
2

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.

SmellydogCoding
  • 414
  • 8
  • 23