Проблемы с интеграцией Vue 3 и Firestore

# #javascript #firebase #vue.js #google-cloud-firestore

Вопрос:

В настоящее время я пытаюсь интегрировать Firebase (и Cloud Firestore) со своим приложением в Vue 3. Я установил firebase@9.0.2 пакет. Мой код и предупреждения консоли ниже.

Кто-нибудь знает, что я делаю неправильно?

firebase.js — файл с моей конфигурацией и инициализацией

 import { initializeApp } from 'firebase/app'
import { getFirestore } from 'firebase/firestore'

const firebaseApp = initializeApp({
  // Firebase app config
})

const db = getFirestore(firebaseApp)

export default db
 

BooksService.js

 import db from '../firebase'
import { collection } from 'firebase/firestore'

const books = collection(db, 'books')

class BooksService {
  getAll () {
    return books
  }
  // other methods
}

export default new BooksService()
 

HelloWorld.vue — пример компонента для отображения списка книг из Firestore

 <template>
  <div>
    <h1>All books</h1>
    <ul>
      <li v-for="book in books" :key="book">
        {{ book }}
      </li>
    </ul>
  </div>
</template>

<script>
import BooksService from '../services/BooksService'

export default {
  data: () => ({
    books: []
  }),

  mounted () {
    this.books = BooksService.getAll()
  }
}
</script>
 

и мои предупреждения и ошибки:

 [Vue warn]: Unhandled error during execution of render function 
  at <HelloWorld msg="Welcome to Your Vue.js App" > 
  at <Home onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy {…} > > 
  at <RouterView> 
  at <App>
[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next 
  at <HelloWorld msg="Welcome to Your Vue.js App" > 
  at <Home onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy {…} > > 
  at <RouterView> 
  at <App>
Uncaught (in promise) TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    |     property 'providers' -> object with constructor 'Object'
    |     property 'Map(8)' -> object with constructor 'Object'
    |     property 'platform-logger =>' -> object with constructor 'Object'
    --- property 'container' closes the circle
    at JSON.stringify (<anonymous>)
    at toDisplayString (shared.esm-bundler.js?9ff4:434)
    at eval (HelloWorld.vue?fdab:7)
    at renderList (runtime-core.esm-bundler.js?5c40:5747)
    at Proxy.render (HelloWorld.vue?fdab:3)
    at renderComponentRoot (runtime-core.esm-bundler.js?5c40:424)
    at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js?5c40:4257)
    at ReactiveEffect.run (reactivity.esm-bundler.js?a1e9:160)
    at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:6656)
    at flushJobs (runtime-core.esm-bundler.js?5c40:6895)
 

Ответ №1:

 const books = collection(db, 'books')

class BooksService {
  getAll () {
    return books
  }
}
 

Отсюда кажется, что вы возвращаете CollectionReference вместо массива документов, который присваивается this.books в вашем компоненте. Попробуйте выполнить рефакторинг до этого:

 import { collection, getDocs } from "firebase/firestore"
const books = collection(db, 'books')

class BooksService {
  getAll () {
    return getDocs(books).then(qSnap => {
        return qSnap.docs.map(d => ({id: d.id, ...d.data()}))
    })
  }
}