I've used the new tree-shakeable version of Firebase SDK, which still seems to produce quite a large chunk, considering what I use it for.
I only use the Firestore part, and have actually moved all Firestore operations to the backend, the only thing I'm doing on the front end is initiating the Firebase app instance and starting a snapshot listener (due to the real-time ability), yet the bundle produced is still 275kb large.
import { initializeApp } from 'firebase/app'
import { getFirestore, collection, doc, onSnapshot, query, where, orderBy } from 'firebase/firestore'
const documents = ref(null)
const firebaseApp = initializeApp(firebaseConfig)
const db = getFirestore(firebaseApp)
const ref = query(collection(db, 'documents'), where(`something`, '==', 'something'), orderBy('createdAt', 'desc'))
const unsub = onSnapshot(ref, (snap) => {
let results = []
snap.docs.forEach(el => {
el.data().createdAt && results.push({ ...el.data(), id: el.id })
})
documents.value = results
}, err => {
console.log(err.message)
documents.value = null
})
Is there a way to reduce that size slightly, without sacrificing the real-time ability?
Related
I've been struggling with Firestore queries.
This is my structure:
I'm simply trying to fetch data where any item of a set of categories belongs to any entry.
So, I'm doing something like it:
firebaseQuery(
entriesRef,
where("categories", "array-contains-any", ["link"])
where("date", ">=", "{SOME DATE BEFORE 01/01/2023}")
orderBy("date", "desc")
)
But result is always empty. Any idea of what could going on?
Thanks!
EDIT
Important information, I've made some tests and seems the getDocs(query) promise is never resolved or rejected (according to logs)
First I didn’t find any firebaseQuery in docs so I have recreated the setup from the provided code and just replaced the firebaseQuery with a query from the official firebase/firestore package.
Here’s the updated code :
import { collection, getDocs, orderBy, query, where } from "firebase/firestore";
import { db } from "./firebase.js";
const ref = collection(db, "entries");
const start = new Date();
console.log(start);
const q = query(
ref,
where("categories", "array-contains-any", ["link"]),
where("date", ">=", start),
orderBy("date", "desc")
);
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data().categories, doc.data().date.toDate());
});
I'm trying to learn Firestore Cloud 9 using a tutorial written for Web version 8. I am stuck trying to refactor what appears to be a subcollection of some sort.
The Web 8 code looks like this:
const ref = firestore.collection('users').doc(auth.currentUser.uid).collection('posts');
const query = ref.orderBy('createdAt');
const [querySnapshot] = useCollection(query);
My (failed) attempt looks something like this:
import { firestore, auth, serverTimestamp } from "#/lib/firebase";
import { collection, getDocs, orderBy, query } from "firebase/firestore";
import { useRouter } from "next/router";
import { useCollection } from "react-firebase-hooks/firestore";
const ref = collection(firestore, 'users');
const q = query(
ref,
where('username', '==', auth.currentUser.uid),
orderBy('createdAt', 'desc')
);
//const newPosts = (await getDocs(q)).docs.map((doc) => doc.data());
const [querySnapshot] = useCollection(q);
I can get the first collection without issue. However grabbing the subcollection (?) via the doc(ument) isn't something I can figure out. I've tried getDocs() (commented out, above) as well as getDoc() & .doc.
This line in the v8 and before syntax:
const ref = firestore.collection('users').doc(auth.currentUser.uid).collection('posts');
Will look like this in v9 and later:
const ref = collection(firestore, 'users', auth.currentUser.uid, 'posts');
Here is the structure of the firestore database
ingredients->(doc name)-> ingredientName: "Apple"
I am trying to figure out the document name of the document with Apple in it but I keep running into an issue where nothing is returned.
async function getIngredientID(){
const q = query(collection(fsdb, 'ingredients'), where('ingredientName', '==', 'Apple'));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
});
}
there is nothing that comes out on the console. At one point I console logged the value of q and there was no document there. All of the StackOverflow answers have to do with Web version 8 but I am working with Web version 9.
I imagine you must have the imports, make sure you have them all correctly. Now import >>fsdb<< make sure to start cloud firestore and get a reference to the service, check that the where method is correct as well as the collection, i don't know what information it has when initializing firebase, it would be nice if you could send more information, if this information does not help you
import { collection, getDocs, query, where } from "firebase/firestore";
import { fsdb } from '../fb';
async function getIngredientID() {
try {
const q = query(
collection(fsdb, "ingredients"),
where("ingredientName", "==", "Apple")
);
const { docs } = await getDocs(q);
const data = docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
} catch (error) {
console.log(error);
}
}
I want to delete a game from my firestore collection, but i get error:
TypeError: doc is not a function
I am using the latest version of Firebase. What is the proper way to delete the doc?
import {where,query,deleteDoc,collection, doc, getDocs, getFirestore } from "firebase/firestore";
deleteGame(game) {
const db = getFirestore();
const q = query(collection(db, "history"), where("date", "==", game.date));
const doc = getDocs(q);
const quer = await getDocs(q);
quer.forEach((doc) =>
{
deleteDoc(doc(db, "history", doc.id));
});
}
According to firebase documentation for delete data you should indeed use
deleteDoc(doc(db, "history", doc.id));
But doc needs to be the function imported from firebase/firestore . You are rewriting the value of doc with the element from quer ( quer.forEach((doc) => ).
You also have const doc = getDocs(q); so you will need change the name of both doc variables in order to use the imported function inside the forEach callback.
Also keep in mind that this won't subcollections (if you have any - as specified in the docs).
I was using the chaining mode of the Firestore Web 8, but I'm in the way of updated it to Module 9 and have been a hard time trying to figure out how to get all the content of my subcollection (collection inside my collection).
My older function is like this and works fine:
function getInfo(doc_name) {
let infoDB = db
.collection("collection_name")
.doc(doc_name)
.collection("subcollection_name")
.get();
return alunoHistorico;
}
so with the module way I tried this code
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
const docRef = doc(db, "collection_name", "doc_name");
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!");
}
but the function doc() expects a even arguments (not counting the db argument) so if I try to use with 3 arguments like this, I get a error:
const docRef = doc(db, "collection_name", "doc_name", "subcollection_name");
to it work I have to pass the exactly document that is inside the subcollection
const docRef = doc(db, "collection_name", "doc_name", "subcollection_name", "sub_doc");
but it doesn't work for me because I have a list os docs inside the subcollection, that I want o retrieve.
So how can I get all my docs inside my subcollection?
Thanks to anyone who take the time.
You need to use collection() to get a CollectionReference instead of doc() which returns a DocumentReference:
const subColRef = collection(db, "collection_name", "doc_name", "subcollection_name");
// odd number of path segments to get a CollectionReference
// equivalent to:
// .collection("collection_name/doc_name/subcollection_name") in v8
// use getDocs() instead of getDoc() to fetch the collection
const qSnap = getDocs(subColRef)
console.log(qSnap.docs.map(d => ({id: d.id, ...d.data()})))
I wrote a detailed answer on difference between doc() and collection() (in V8 and V9) here:
Firestore: What's the pattern for adding new data in Web v9?
If someone want to get realtime updates of docs inside sub collection using onSnapshot in Modular Firebase V9, you can achieve this like:
import { db } from "./firebase";
import { onSnapshot, collection } from "#firebase/firestore";
let collectionRef = collection(db, "main_collection_id", "doc_id", "sub_collection_id");
onSnapshot(collectionRef, (querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log("Id: ", doc.id, "Data: ", doc.data());
});
});