How to get nested key in firebase real time database - javascript

I am creating a database for the products. The products are pushed into the database successfully but I am facing a problem in getting the data because the keys are nested. How can I target the nested key?
Please help me.
Using the below code I am getting my all the products data of currently logged in user.
useEffect(() => {
const getProductsData = async () => {
const userId = await AsyncStorage.getItem('uid')
database()
.ref(`Products/${userId}`)
.on('value', data => {
console.log(data.val())
});
}
getProductsData()
}, [])
console of the data.val()

Assuming that your userId is the dUD7M... value in the screenshot you shared, the data snapshot you get will contain the data for both child nodes in that screenshot. You can loop over those children with:
const userId = await AsyncStorage.getItem('uid')
database()
.ref(`Products/${userId}`)
.on('value', snapshot => {
snapshot.forEach((data) => { // 👈
console.log(data.val())
});
});

Related

array.prototype..forEach function skipped with values in variable

I have a problem, i have a Firebase Firestore Database connected to my React.JS Project, where users can enroll to courses. Now if i'm trying to load the users collection from the DB it returns 1 entry.
const fetchAthletes = async () => {
debugger
try {
const athletes: Array<any> = [];
const athleteRef = collection(db, COLLECTION_NAME_ATHLETE);
const getAthleteQuery = query(athleteRef, where('user', '==', userAuthToken.accessToken));
const querySnapshot = await getDocs(getAthleteQuery)
if (querySnapshot.docs) {
//this for each gets skipped, even when querySnapshot.doc has values in it
querySnapshot.forEach((doc) => {
athletes.push({
id: doc.id,
...doc.data()
});
setAthletes(athletes as Array<Athlete>);
})
}
} catch (error: unknown) {
enqueueSnackbar((error as string), { variant: 'error', autoHideDuration: 3000 })
}
}
But when i want to loop over it via array.prototype.map it always skips it.
I debbuged through the funtion and found out that docs from Firestore is set with values tbat i wanna recieve.
Data returned by Firestore
I have no clue why it doesn't work. Any idea or help is appreciated
Rather than attempt to individually set each doc into state, build up your array and set the entire thing into state
const querySnapshot = await getDocs(getAthleteQuery);
setAthletes(querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));

How to fetch all the documents with unique id from firestore database using React?

[Firestore SS][1]
[1]: https://i.stack.imgur.com/EI1Dm.png
I want to fetch each document as displayed in SS it's stored as Pets + unique_userId.
I am unable to fetch all data together. Just able to fetch one data of a particular user using the code below.
const [info,setInfo]=useState([]);
useEffect(() => {
db.collection("pets ESYXOPqlJpZ48np8LfNivnh9pvc2").onSnapshot((snapshot) =>
setInfo(snapshot.docs.map((doc) => doc.data()))
);
},[]);
Here ESYXOPqlJpZ48np8LfNivnh9pvc2 this is the userID of each unique user
Please help me out to fetch all the Pets data instead of hardcoding and fetching one particular data.
Try the following code,
const [docs, setDocs] = useState([]);
useEffect(() => {
const querySnapshot = await getDocs(collection(db,"pets ESYXOPqlJpZ48np8LfNivnh9pvc2"));
const document =[];
querySnapshot.forEach((doc) => {
document.push({
...doc.data(),
id: doc.id
});
});
setdocs(document);
}, []);
I'm guessing the appended id is a reference to the owner's id? In this case, would it be an option to fetch the owner list and use everyone's id to build a list of collection ids and then get all of their data?
If not, I only see to options:
Rethink your database structure - maybe use a unified pets collection and have a reference with/to that id in the pet documents.
Create a cloud function in which use #google-cloud/firestore to get the list of collections. There are tons of resources out there to help you get started with firebase cloud functions. Their documentation is pretty good also, and probably the most up-to-date
const functions = require('firebase-functions')
const { Firestore } = require('#google-cloud/firestore');
module.exports = functions
.region('europe-west3') // use the region you want here
.https.onRequest(async (request, response) => {
try {
const firestore = new Firestore();
const collections = (await firestore.listCollections()).map(collection => collection.id)
response.json({ data: collections })
} catch (error) {
response.status(500).send(error.message)
}
})
You'll get and endpoint which you can use to fetch the collection ids (e.g.: https://your-project-name.cloudfunctions.net/collections)
const [pets, setPets] = useState([]);
const [collectionIds, setCollectionIds] = useState([])
useEffect(() => {
fetch('https://your-project-name.cloudfunctions.net/collections')
.then(response => response.json())
.then(({ data }) => setCollectionIds(data))
}, [])
useEffect(() => {
collectionIds.forEach((collectionId) => {
// There are better ways to do this,
// I'm just using your approach so you can focus on the rest of the code
db.collection(collectionId).onSnapshot((snapshot) => {
setPets((currentPets) => [...currentPets, ...snapshot.docs.map((doc) => doc.data())])
})
})
}, [collectionIds])
Please note that these are very high-level implementations, there's no error handling, no teardowns or anything, so keep that in mind. Hope it helps, good luck!

Unable to retrieve data from Multiple collection firebase

Hope you're in good health.
I have a problem.
export function fetchListing() {
return function (dispatch) {
dispatch(fetchListingRequest());
//Getting Listing where status is in_review
firebase
.firestore()
.collection("listings")
.where("status", "==", "in_review")
.onSnapshot(
snapshot => {
const data = [];
snapshot.docs.forEach(doc => {
const temp = {};
// Getting address of business
firebase
.firestore()
.collection("users")
.doc(doc.data().business_id)
.get()
.then(users => {
temp["address"] = users.data().address;
})
.catch(error => {
dispatch(fetchListingFailed(error));
});
temp["title"] = doc.data().title;
temp["description"] = doc.data().description;
temp["listing_file"] = doc.data().listing_file;
data.push([doc.id, temp]);
});
dispatch(fetchListingSucess(data));
},
error => {
dispatch(fetchListingFailed(error));
}
);
};
}
I am Unable to get address in state but when I log it It displayed in console. I am able to access address when I am retrieving it from firebase and also in reducer I am also getting address.
reasons can be :
The hierarchy of your firestore collection
or you have to know that in js you can't affect the data to a variable that is in the main prog just when it is in a one level functions
for exemple here you can do this
locale = this ;
than you can use all the variables in two other levels

Cannot fetch list of UIDs inside "users" collection in firebase using reactjs

constructor(props) {
super(props);
this.state = {
users:[]
};
}
//method to get the data from users collection
async componentDidMount() {
const db = firebase.firestore();
db.collection("users")
.get()
.then(querySnapshot => {
const data = querySnapshot.docs.map(doc => doc.data());
console.log(data);
this.setState({ users: data });
})
.catch( err =>{
console.log(err);
});
}
this function returning an empty error
i want to print list of users uid
here i have users collection and inside it i have retailers collection and its document
One thing you have to realize here is that your users collection contains no documents. The document IDs are shown in italics, which means that there is no document here. The IDs are visible because there is a nested subcollection under each document. They are shown like this in the console so that you can click through and navigate to the nested subcollection, despite the document being missing.
If you want to list users with a query, you will have to actually create documents in the users collection. They can be empty if you don't have any information. But you do need actual documents in the users collection in order for anything to show up in a query.
This line in your current code querySnapshot.docs.map(doc => doc.data()) takes the data of each document. But you're keeping the UID in the ID of each document, so you'll want to use:
const db = firebase.firestore();
db.collection("users")
.get()
.then(querySnapshot => {
const data = querySnapshot.docs.map(doc => doc.id);
console.log(data);
this.setState({ users: data });
})
.catch( err =>{
console.log(err);
});
Update: As Doug pointed out in his answer, if there are no actual user documents, your get() call will not return it.
I highly recommend creating user documents, even if it's just an empty one.
For now, the only way to get the UID would be to load all retailers for all users, and then use those results to get the ID of the parent documents:
const db = firebase.firestore();
db.collectiongroup("retailers")
.get()
.then(querySnapshot => {
querySnapshot.forEach((doc) => {
console.log("retailed "+doc.id+" for user "+doc.ref.parent.parent.id);
});
})
.catch( err =>{
console.log(err);
});
You'll have to deduplicate the UIDs, but that will leads to getting the UIDs.
But you'll be loading all retailers for all users this way, so as said, I highly recommend storing a small/empty user document instead.
The data method on querySnapshot.docs gets the data now to get the id of each document you need to add access the id property as UID is stored in id property
async componentDidMount() {
const db = firebase.firestore();
db.collection("users")
.get()
.then(querySnapshot => {
const data = querySnapshot.docs.map(doc => doc.data().id);
console.log(data);
this.setState({ users: data });
})
.catch( err =>{
console.log(err);
});
}

Get Cloud Firestore database collection

I'm trying to get data from my database hierarchy db.collection/doc/collection/
I need to get the data from the collection "product"
I can already filter out the right document, by using this snippet.
Still, didn't manage to get any data from the next collection.
db.collection('deliveryservice').where('owner_id', '==', user.uid).collection('product').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
Please try the following way to retrieve data from your product collection.
var docRef = db.collection("deliveryservice").doc(user.uid).collection('product');
docRef.get().then((snapshot) => {
snapshot.docs.forEach(doc => {
}
}).catch(function(error) {
console.log("Error getting document:", error);
})

Categories