Why I receive "TypeError: doc is not a function" (Firebase 9, Firestore) - javascript

I try to add a user in Firestore with a custom ID.
import { db } from "../firebase/config";
import {collection, addDoc, deleteDoc, updateDoc, doc, setDoc} from 'firebase/firestore'
export const useFirestore = (collections) => {
const addDocumentUser = async (doc, id) => {
try{
const addedDocument = await setDoc(doc(db, collections, id), {...doc});
return addedDocument.id
}
catch(err){
console.log(err)
dispatch({type: 'ERROR', payload: err})
}
}
return {addDocumentUser}
}
When I run it I receive following error in the consol:
TypeError: doc is not a function
at addDocumentUser (useFirestore.js:62:1)
at useSignup.js:29:1
at async signup (useSignup.js:23:1)
at async handleSubmit (Signup.js:23:1)
What I am doing wrong?
I imported everything and the database access works for functions (addDoc) without the custom id.

The problem is that you're redefining doc, so it has two definitions:
import { db } from "../firebase/config";
import {collection, addDoc, deleteDoc, updateDoc, doc, setDoc} from 'firebase/firestore'
// 👆
export const useFirestore = (collections) => {
const addDocumentUser = async (doc, id) => {
// 👆
try{
const addedDocument = await setDoc(doc(db, collections, id), {...doc});
...
That second doc that I point out hides the function that you import before.
The solution is to use a different name:
import { db } from "../firebase/config";
import {collection, addDoc, deleteDoc, updateDoc, doc, setDoc} from 'firebase/firestore'
export const useFirestore = (collections) => {
const addDocumentUser = async (data, id) => {
// 👆
try{
const addedDocument = await setDoc(doc(db, collections, id), {...data});
// 👆
...

Related

How to map firebase documents using javascript?

I need to display transaction data in interface, but i dont understand how to map documents to see different data in each doc.
import React, { useContext, useEffect, useState } from "react";
import "firebase/compat/auth";
import "firebase/compat/firestore";
import { db } from "../../firebase";
import { doc, getDoc } from "firebase/firestore";
import { UserContext } from "../../context/UserContext";
const TransactionHistoryComponent = () => {
async function getUserTransaction() {
const docRef = doc(
db,
"transactions",
txhash,
"userTransactions",
"5TS44z5iPOzWaj3F4uRr"
);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
console.log("Document data:", docSnap.data());
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}
const { txhash } = useContext(UserContext);
useEffect(() => {
getUserTransaction();
i tried to enter a name of document and this works but only with one document. i need to see 1, 2, and 32744342390493 document data in interface by some sort of mapping this documents

Firestore get count for a collection not working

I have this code:
import { getCountFromServer } from 'firebase/firestore'
useEffect(()=> {
const getCount = async () => {
const collection = userDB().collection('invoices')
const query = collection.where('status', '==', 'paid')
const snapshot = await getCountFromServer(query)
setCount(snapshot.data().count)
}
getCount().catch(err=> console.log(err))
}, [user, collectionRef, filterKey, filterValue])
Where userDB() is the same as db.collection('users').doc(userid')
Yet this throughs an error:
TypeError: Cannot read properties of undefined (reading '_t')
at gn (index.esm2017.js:4251:1)
at bu (index.esm2017.js:13685:1)
at Ca.run (index.esm2017.js:16797:1)
at index.esm2017.js:20050:1
I have followed the docs: https://firebase.google.com/docs/firestore/query-data/aggregation-queries#web-version-9_1
Currently using:
"firebase": "^9.15.0",
userDB is defined in a ts file like so:
export const userDB = () => {
let user = auth.currentUser
return db.collection('users').doc(user?.uid)
}
Here is the initlizer file:
import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import 'firebase/compat/auth';
const firebaseApp = firebase.initializeApp ({
...keys
});
export const Providers = {
google: new firebase.auth.GoogleAuthProvider(),
};
const db = firebaseApp.firestore()
const auth = firebase.auth();
const Fire = firebaseApp
export {db, Fire, auth}
You should not uses both compat and modular SDKs together. The compat version does not support count queries. I would recommend updating your code to use the new syntax:
import { initializeApp } from 'firebase/app';
import { getFirestore } 'firebase/firestore';
import { getAuth, GoogleAuthProvider } 'firebase/auth';
const firebaseApp = initializeApp({
...keys
});
export const Providers = {
google: new GoogleAuthProvider(),
};
const db = getFirestore()
const auth = getAuth();
export { db, auth }
import { db } from '...'
import { collection, query, where, getCountFromServer } from 'firebase/firestore'
useEffect(()=> {
const getCount = async () => {
const q = query(collection(db, 'invoices'), where('status', '==', 'paid'))
const snapshot = await getCountFromServer(q)
setCount(snapshot.data().count)
}
getCount().catch(err=> console.log(err))
}, [user, collectionRef, filterKey, filterValue])

How to check whether I'm getting data from cache or firestore (JavaScript SDK)?

I enabled the firestore cache by calling the enableIndexedDbPersistence method in my react app. here is my code:
import { initializeApp } from "firebase/app"
import { getAuth } from "firebase/auth"
import { enableIndexedDbPersistence, getFirestore } from "firebase/firestore"
const firebaseConfig = {
// config code
}
initializeApp(firebaseConfig)
const db = getFirestore()
enableIndexedDbPersistence(db) // enable cache
const auth = getAuth()
export { auth, db }
I would like to know how I can verify that I'm getting data from the cache, not from the server in the below code?
import { useEffect, useState } from "react"
import { collection, limit, onSnapshot, orderBy, query, where } from "firebase/firestore"
import { db } from "../firebase/config"
export const useCollection = (c) => {
const [documents, setDocuments] = useState([])
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
let ref = collection(db, c)
const unsubscribe = onSnapshot(ref, (snapshot) => {
const results = []
console.log(snapshot.metadata.fromCache ? "local data" : "server data")
snapshot.docs.forEach(
(doc) => {
results.push({ ...doc.data(), id: doc.id })
},
(error) => {
console.log(error)
setError("could not fetch the data")
}
)
setDocuments(results)
setIsLoading(false)
setError(null)
})
return () => unsubscribe()
}, [])
return { documents, error, isLoading }
}
Is there anything apart from calling the enableIndexedDbPersistence method I need to do to configure the cache properly?
Will this method cache the subcollection documents as well?

Firebase not accept more fields for a document

I have a html modal for inputting data into Firebase's Firestore but it's not accepting more than the first 2 inputs and even though I removed the line that put the server timestamp on each document its still adding it to the documents. Below is the javascript code that I used :
import { initializeApp } from 'firebase/app'
import {
getFirestore, collection, onSnapshot,
addDoc, deleteDoc, doc,
query, where,
orderBy,
getDoc, updateDoc
} from 'firebase/firestore'
import {
getAuth, createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
onAuthStateChanged
} from 'firebase/auth'
initializeApp(firebaseConfig)
const db = getFirestore()
const colRef = collection(db, 'Guides')
//adding docs
const addGuideForm = document.querySelector('.add')
addGuideForm.addEventListener('submit', (e) => {
e.preventDefault()
addDoc(colRef, {
title: addGuideForm.title.value,
content: addGuideForm.content.value,
test: addGuideForm.content2.value,
verif: addGuideForm.verif.value,
})
.then(() => {
addGuideForm.reset()
})
})

Read Collection in firebase from vue js

I am trying to read a collection with specific name from firebase firestore, but I get an error which I couldn't find answer for it.
Here you can see my boot file:
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";
import { collection, query, where, doc, getDoc } from "firebase/firestore";
const firebaseApp = initializeApp({
apiKey: "####",
authDomain: "####",
projectId: "####",
});
const db = getFirestore();
const auth = getAuth();
const createUser = createUserWithEmailAndPassword();
export default {db, auth, createUser};
Here is my script tag in .vue file:
<script>
import { collection, getDocs } from "firebase/firestore";
import db from "src/boot/firebase"
export default {
setup() {
return {
waitingList: {},
};
},
created() {
const querySnapshot = await getDocs(collection(db, "waitingList"));
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
console.log(doc.name, " => ", doc.data());
});
},
};
</script>
and here you can see the list of errors I got:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'tenantId')
FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore
The imported db would be an object containing instances of Firestore and Auth. Try changing your import as shown below:
import { db } from "src/boot/firebase"
// instead of import db from "..."
export default {
setup() {
return {
waitingList: {},
};
},
async created() {
const querySnapshot = await getDocs(collection(db, "waitingList"));
querySnapshot.forEach((doc) => {
console.log(doc.name, " => ", doc.data());
});
},
};
Also change export default { db } to export { db } in the boot file.

Categories