Get documents name in Firestore and create nested object - javascript

This question is related to this one: Get documents names in Firestore but I can't comment yet.
I am trying to get a nested object from my FireStore which looks like this
{"docname1": {…}, "docname2": {…}, "docname3": {…}}
I have this now but cant seem to figure out how to create the nested object to push it into the empty array.
useEffect(() => {
const getPlants = async () => {
let response = []
const querySnapshot = await firebase
.firestore()
.collection('plants')
.get()
querySnapshot.forEach((doc) => {
let newObject = [doc.id: doc.data() ]
response.push(newObject)
})
setPlants(response)
}
getPlants()
}, [])
Any help is greatly appreciated :)

I think you are creating the new object (newObject) wrong. Try to create it like this:
querySnapshot.forEach((doc) => {
const newObject = {}
newObject[doc.id] = doc.data()
response.push(newObject)
})
Or, you can do this:
querySnapshot.forEach((doc) => {
response.push({ [`${doc.id}`]: doc.data() })
})

Related

real time update with firestore duplicating array at each update while using multiple queries

im using firebase cloud firestore as my database i used to do onSnapshot data enquiry and all was cool but i used to get data for one query so there was no problem now i want to collect mutiple data by multiple queries in one array and i have got it work but each time i update a document data will be duplicated (new arrays are created) any idea?this is an example of my code where multiple users(doctors) each one will collect data from his own collection then data are pushed to one array:
` async getPatientsAll(doctors) {
const fetchPromises=[]
doctors.forEach(async (doctor) => {
const patientsCollectionAllRef = collection(db, 'users',doctor.id,'patients')
const patientsCollectionAllQuery = query(patientsCollectionAllRef, orderBy('date', 'desc'))
this.loading=true
getPatientsSnapshot=onSnapshot(patientsCollectionAllQuery, async (querySnapshot) => {
const patients=[]
querySnapshot.forEach((doc) => {
let patient={
id:doc.id,
details:doc.data().details,
date:doc.data().date,
namef:doc.data().namef,
age:doc.data().age,
gender:doc.data().gender,
phone:doc.data().phone,
}
patients.push(patient)
})
await Promise.all(patients.flatMap(async (patient) => {
fetchPromises.push(patient)
}))
//indexing
this.patients.forEach((patient, index) => {
patient.index = this.patients.length - index})
this.loading=false
},error=>{
console.log('error',error.message)
})
})
this.patients=fetchPromises
console.log('chao',fetchPromises)
},`
and this is the code that used to work perfectly without data duplication just updating a document the document only will be updated without adding a new array and by the way all this was using pinia store to get the data
async getPatients() {
this.loading=true
getPatientsSnapshot=onSnapshot(patientsCollectionQuery, (querySnapshot) => {
const patients=[]
querySnapshot.forEach((doc) => {
let patient={
id:doc.id,
details:doc.data().details,
date:doc.data().date,
namef:doc.data().namef,
age:doc.data().age,
gender:doc.data().gender,
phone:doc.data().phone,
}
patients.push(patient)
})
this.patients=patients
//indexing
this.patients.forEach((patient, index) => {
patient.index = this.patients.length - index})
this.loading=false
},error=>{
console.log('error',error.message)
})
},

How to get specific data from all documents from a collection in firebase?

Platform: React Native (Expo)
So I'm trying to get two values (dotCoins and name) from my firebase db and I can't figure out how to go about it. Here's my firebase structure:
This is what I currently have in place:
// Calling function when screen loads
componentDidMount() {
this.getDotCoins();
this.getUserData();
}
// Calling function when it updates
componentDidUpdate() {
this.getDotCoins();
this.getUserData();
}
// The function
getUserData = async () => {
const querySnapshot = await getDocs(collection(db, "users"));
const tempDoc = [];
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
});
console.log(tempDoc);
};
Both the console.log() prints nothing, and my console remains absolutely empty. I can't find where I'm going wrong since I don't receive any errors too. (I have all packages installed correctly and all functions imported too)
You are not pushing any document data to tempDoc so it'll always be empty. Try refactoring the code as shown below:
getUserData = async () => {
const querySnapshot = await getDocs(collection(db, "users"));
const tempDoc = querySnapshot.docs.map((d) => ({
id: d.id,
...d.data()
}));
console.log(tempDoc);
};
const q = query(collection(db, "users"));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(doc.data())
})
});
});
return unsubscribe;

How do I convert the firestore data to a JSON object?

I have these codes:
const App = () => {
const [users, setUsers] = useState();
const getData = async () => {
const citiesRef = firestore.collection("users");
const snapshot = await citiesRef
.where("item.itemName", "==", true)
.where("item", "==", false)
.get();
if (snapshot.empty) {
console.log("No matching documents.");
return;
}
snapshot.forEach((doc) => {
console.log(doc.data());
});
};
useEffect(() => {
getData();
});
return <div>Month</div>;
};
export default App;
If I'll console.log(doc.data()) this is what is shows:
How can I convert this into a JSON object?
I wanted to have a JSON object in order to filter the data. Thank you.
If you are trying to get an array of objects containing all documents' data to filter them, try this:
const usersData = snapshot.docs.map(d => ({id: d.id, ...d.data()}))
// set this array in your state
setUsers(usersData)
This will be an array and you can use methods like filter(), find() as required. For example, to get users having admin role in their roles array:
const admins = usersData.filter(user => user.roles.includes("admin"))

How do i retrieve all documents from a collection and its relevant information? (React Native Firebase)

Firebase hierarchy image
I have a collection named "Tickets"
Inside the collection contains many ticketID and its relevant information.
How can I display all the TicketID and the information in each sub ticket??
I am using React Native and Firebase.
Firebase design
I've tried doing this:
firebase.firestore()
.collection("tickets")
.get()
.then(querySnapshot => {
const documents = querySnapshot.docs.map(doc => doc.data())
// do something with documents
console.log(documents);
})
And the result is:
Array []
Right now you are querying for the tickets, and you should be getting their data e.g. the fields for each ticket. But you want data for the ticket's subcollection, 'userTickets'.
You can get data for all 'userTickets' subcollections by using a collection group query:
firebase.firestore()
.collectionGroup('userTickets')
.get()
.then((querySnapshot) => {
const documents = querySnapshot.docs.map((doc) => doc.data());
// do something with documents
console.log(documents);
});
import { AngularFirestore } from '#angular/fire/firestore';
constructor(private db: AngularFirestore) {}
getTickets() {
return this.db.collection('tickets').get().then(querySnapshot => {
const tickets = querySnapshot.docs.map(doc => doc.data())
// you can call getUserTicketsById here to add data from userTicket collection to ticket
// ticktes.forEach(ticket => {const ticketData = this.getUserTicketsById(ticket.id); ticket.userTicket = ticketData})
console.log(tickets);
return tickets;
})
}
getUserTicketsById(userId) {
return this.db.collection(`tickets/${userId}/userTickets`).get().then(querySnapshot => {
const userTickets = querySnapshot.docs.map(doc => doc.data())
// do something with documents
console.log(userTickets);
return userTickets;
})
}

How to add doc ID to every element of querySnapshot from firestore query?

I am trying to add the document ID from each doc in the query snapshot to the corresponding element in the array I am pushing then committing to state.
I need the document ID in my state so I can query specific docs by there id in order to update them.
I am currently looping through the snapshot with forEach() like the google docs suggest but I am trying to use map() to put each element in my let cards =[] array but also include the doc.id in the element somewhere.
actions: {
async nuxtServerInit(vuexContext, context) {
let cards = []
await db
.collection('Assets')
.get()
.then(snapshot => {
snapshot.forEach(doc => {
cards.map(doc.data())
})
vuexContext.commit('setCards', cards)
})
},
Currently in my state I am still seeing
loadedCards:Array[1]
0:Object
authors:"noFace1"
description:"hopefully this fucking works"
imageurl:Array[1]
slug:"the-big-test-bunny"
title:"The big test bunny"
type:"Video"
user:"VbomJvANYDNe3Bek0suySs1L8oy1"
I need to have another property of id: xblkujoifduodsifl (just example id) included in my state.
change this line cards.map(doc.data()) for this
cards.map(doc => {
const id = doc.id
const data = doc.data()
return Object.assign({}, id, { ...data })
})
the id is not part of the doc unless you explicit copy it
This is are more verbose solution from my code that worked:
.db
.collection("organizations")
.doc(activeOrganization)
.collection("people")
.get()
.then((snapshot) => {
if (!snapshot.empty) {
let people = [];
snapshot.forEach((doc) => {
let dict = { ...doc.data(), id: doc.id};
people.push(dict);
});
console.log(people);
} else {
reject("No document corresponding to the query!");
}
})
.catch((err) => reject(err));

Categories