【问题标题】:Vue.js Cannot read property 'collection' of undefinedVue.js 无法读取未定义的属性“集合”
【发布时间】:2021-02-07 11:03:49
【问题描述】:

我正在使用 Vue.js 和 firestore 为我的项目制作登录页面,我尝试制作一个注册表单来为我的网站创建新帐户。

我在我的 firebase 项目中创建了一个名为“users”的集合,其中存储了注册完成时的用户信息。但是当我调用该函数时,出现了错误:

无法读取未定义的属性“集合”

我能做什么?我将在这里分享我的代码:

注册.vue

import { Auth, db, usersCollection } from '@/firebase/auth.js'
import * as fb from 'firebase'
import {App} from '@/firebase/app.js'

async addEmail(email,password) {
      var noticeMessage = "???? Your account has been reserved ????"
      const {user} = await Auth.createUserWithEmailAndPassword(email, password )
      await fb.usersCollection.doc(user.uid).set({
      email: email,
      password: password,
      userId: user.uid,
      createdAt: new Date().toISOString(),
    })

auth.js

import {App} from './app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/storage';

var config = {
    apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    authDomain: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    databaseURL: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    projectId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    storageBucket: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    messagingSenderId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    appId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    measurementId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }

export const Auth = App.auth();
export const db = App.firestore();
export const usersCollection = db.collection('users')

app.js

import Firebase from 'firebase/app'
import credentials from './credentials'


export const App = Firebase.initializeApp(credentials.config);

【问题讨论】:

    标签: javascript firebase vue.js google-cloud-firestore


    【解决方案1】:

    async-firestore.js

    import firebase from 'firebase/app'
    import { isNil } from 'lodash'
    
    let asyncFirestore = null
    
    // Lazy load firestore with async import is important for performance
    
    export default () => {
      if (isNil(asyncFirestore)) {
        asyncFirestore = import(/* webpackChunkName: "chunk-firestore" */ 'firebase/firestore').then(
          () => {
            firebase.firestore().settings({})
            firebase.firestore().enablePersistence({ synchronizeTabs: true })
            return firebase.firestore()
          }
        )
      }
      return asyncFirestore
    }
    

    generic-db.js

    import { isNil, keys, cloneDeep } from 'lodash'
    import firebase from 'firebase/app'
    
    import firestore from './async-firestore'
    
    export default class GenericDB {
      constructor(collectionPath) {
        this.collectionPath = collectionPath
      }
    
      /**
       * Create a document in the collection
       * @param data
       * @param id
       */
      async create(data, id = null) {
        const collectionRef = (await firestore()).collection(this.collectionPath)
        const serverTimestamp = firebase.firestore.FieldValue.serverTimestamp()
    
        const dataToCreate = {
          ...data,
          createTimestamp: serverTimestamp,
          updateTimestamp: serverTimestamp
        }
    
        const createPromise = isNil(id)
          ? // Create doc with generated id
            collectionRef.add(dataToCreate).then(doc => doc.id)
          : // Create doc with custom id
            collectionRef
              .doc(id)
              .set(dataToCreate)
              .then(() => id)
    
        const docId = await createPromise
    
        return {
          id: docId,
          ...data,
          createTimestamp: new Date(),
          updateTimestamp: new Date()
        }
      }
    
      /**
       * Read a document in the collection
       * @param id
       */
      async read(id) {
        const result = await (await firestore())
          .collection(this.collectionPath)
          .doc(id)
          .get()
    
        const data = result.exists ? result.data() : null
    
        if (isNil(data)) return null
    
        this.convertObjectTimestampPropertiesToDate(data)
        return { id, ...data }
      }
    
      /**
       * Read all documents in the collection following constraints
       * @param constraints
       */
      async readAll(constraints = null) {
        const collectionRef = (await firestore()).collection(this.collectionPath)
        let query = collectionRef
    
        if (constraints) {
          constraints.forEach(constraint => {
            query = query.where(...constraint)
          })
        }
    
        const formatResult = result =>
          result.docs.map(ref =>
            this.convertObjectTimestampPropertiesToDate({
              id: ref.id,
              ...ref.data()
            })
          )
    
        return query.get().then(formatResult)
      }
    
      /**
       * Update a document in the collection
       * @param data
       */
      async update(data) {
        const { id } = data
        const clonedData = cloneDeep(data)
        delete clonedData.id
    
        await (await firestore())
          .collection(this.collectionPath)
          .doc(id)
          .update({
            ...clonedData,
            updateTimestamp: firebase.firestore.FieldValue.serverTimestamp()
          })
    
        return id
      }
    
      /**
       * Delete a document in the collection
       * @param id
       */
      async delete(id) {
        return (await firestore())
          .collection(this.collectionPath)
          .doc(id)
          .delete()
      }
    
      /**
       * Convert all object Timestamp properties to date
       * @param obj
       */
      convertObjectTimestampPropertiesToDate(obj) {
        const newObj = {}
    
        keys(obj)
          .filter(prop => obj[prop] instanceof Object)
          .forEach(prop => {
            if (obj[prop] instanceof firebase.firestore.Timestamp) {
              newObj[prop] = obj[prop].toDate()
            } else {
              this.convertObjectTimestampPropertiesToDate(obj[prop])
            }
          })
    
        return {
          ...obj,
          ...newObj
        }
      }
    }
    

    init.js

    import firebase from 'firebase/app'
    import 'firebase/auth'
    
    const config = {
      apiKey: ...,
      authDomain: ...,
      databaseURL: ...,
      projectId: ...,
      storageBucket: ...,
      messagingSenderId: ...,
      appId: ...,
    }
    
    firebase.initializeApp(config)
    

    users-db.js

    import GenericDB from './generic-db'
    
    export default class UsersDB extends GenericDB {
      constructor() {
        super('users')
      }
    }
    

    ma​​in.js

    ...
    // firebase setup
    import './firebase/init'
    ...
    
    

    你可以像这样进行firebase身份验证

    import firebase from 'firebase/app'
    ...
          const { user } = await firebase
            .auth()
            .createUserWithEmailAndPassword(form.email, form.password)
    
          // create a user in firestore `users` table
          const userDb = new UsersDB()
          const newUser = {
            email: form.email,
            name: form.name,
          }
          userDb.create(newUser, user.uid)
    ...
    

    【讨论】:

    • 更改后,我有这 2 个错误:1) "FirebaseError: [code=invalid-argument]: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined", 2) 使用无效数据调用的函数 DocumentReference.set()。不支持的字段值:未定义
    • 好的。我将添加另一个答案我如何在 vue 中处理 firebase。
    猜你喜欢
    • 2020-07-05
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 2020-05-12
    • 2018-07-27
    • 1970-01-01
    相关资源
    最近更新 更多