Reputation: 271
I'm using Vue.js and firestore to make a landing page for my project, I've tried to make a registration form to make new account for my website.
I've created a collection in my firebase project, named "users", where the user information where stored when the sign up completed. But when I call the function, the error appeared:
Cannot read property 'collection' of undefined
What can I do? I'll share my code here:
Signup.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);
Upvotes: 1
Views: 398
Reputation: 1984
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')
}
}
main.js
...
// firebase setup
import './firebase/init'
...
You can do firebase auth like this
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)
...
Upvotes: 1