How to get values of object in firestore - firebase

Im trying to implement code in Firestore which will get the values of a specific object inside a doc in firestore, unfortunently i couldnt find the way to do it.
This is my query code:
useEffect(() => {
firebase
.firestore()
.collection("users")
.doc(uid)
.collection("confirmed-appointments")
.get()
.then((snapshot) => {
let service = [];
snapshot.forEach((doc) => {
service.push(doc.data());
});
console.log("Services: ", service[0].servicesSelected); //Checking if i can get the serviceSelected Obj
});
}, []);
This is a image of the firestore:
What i want is to get the data of the Red circle object, move it to a local object in the code and then present its data inside the app.
any suggestions?

As far as I can tell from the above images, document 10 contains an array, which means that you will need to index into that array in order to get its elements. You can leverage the following code to fetch the servicesSelected object fields:
import firestore from '#react-native-firebase/firestore';
firestore()
.collection('users')
.doc(uid)
.collection("confirmed-appointments")
.get()
.then(querySnapshot => {
//let service = [];
console.log('Total confirmed appointments: ', querySnapshot.size);
querySnapshot.forEach(documentSnapshot => {
console.log("Services Selected: ", documentSnapshot.data().YOUR_ARRAY[1].servicesSelected);
//service.push(documentSnapshot.data());
//console.log('Appointment ID: ', documentSnapshot.id, documentSnapshot.data());
});
});
Note that I assume that servicesSelected lives at index 1 of YOUR_ARRAY (replace YOUR_ARRAY with its actual name).
You can refer to the officially recommended documentation for more details about React Native for Firebase.

Related

How to access all documents, my all documents only have sub collection in firestore

I have create document like this in react native, I am using rnfirebase library
firestore()
.collection('WaterCanData')
.doc(EntryDate)
.collection('Entries')
.doc(values.customerName)
.set({
CustomerName: values.customerName,
CansOut: values.cansOut,
JarsOut: values.jarsOut,
EmptyCansIn: values.emptyCansIn,
JarsIn: values.jarsIn,
Bottles: values.bottles,
Ice: values.ice
})
.then(() => {
console.log('Entry added!!!!!!!!!');
})
When I try to retrieve EntryDate from WaterCanData Coellection I am not able to fetch it(Document name appears in italic font), So how should I retrive this document which contains a subcollection, Below I have attached my ss of data structure
Data structure
Data structuree
The reason your document appears in italics is because it doesn't currently exist. In Cloud Firestore, subcollections can exist without requiring their parent document to also exist.
Non-existant documents will not appear in queries or snapshots in the client SDKs as stated in the Firebase Console.
This document does not exist, it will not appear in queries or snapshots
If you want to be able to get your entry dates, you need to create the document (which can be empty).
firebase.firestore()
.collection('WaterCanData')
.doc(EntryDate)
.set({}); // an empty document
To create the document at the same time as an entry on it's subcollection, you can use a batched write like so:
const db = firebase.firestore();
const batch = db.batch();
// get references to the relevant locations
const entryDateRef = db
.collection('WaterCanData')
.doc(EntryDate);
const customerRef = entryDateRef
.collection('Entries')
.doc(values.customerName);
// queue the data to write
batch.set(entryDateRef, {});
batch.set(customerRef, {
CustomerName: values.customerName,
CansOut: values.cansOut,
JarsOut: values.jarsOut,
EmptyCansIn: values.emptyCansIn,
JarsIn: values.jarsIn,
Bottles: values.bottles,
Ice: values.ice
})
// make changes to database
batch.commit()
.then(() => {
console.log('Entry added!!!!!!!!!');
});
This will then allow you to list all of the entry dates in your database using something like:
firebase.firestore().collection('WaterCanData')
.get()
.then((querySnapshot) => {
querySnapshot.forEach(doc => {
const entryDate = doc.id;
// const customerEntriesRef = doc.ref.collection('Entries');
console.log('Entry date found: ' + entryDate);
}
});
If (as an example) you wanted to also find how many entries were linked to a given date, you would need to also query each subcollection (here the code gets a little more confusing).
firebase.firestore().collection('WaterCanData')
.get()
.then((querySnapshot) => {
const fetchSizePromises = [];
// for each entry date, get the size of it's "Entries" subcollection
querySnapshot.forEach(doc => {
const entryDate = doc.id;
const customerEntriesRef = doc.ref.collection('Entries');
// if this get() fails, just store the error rather than throw it.
const thisEntrySizePromise = customerEntriesRef.get()
.then(
(entriesQuerySnapshot) => {
return { date: entryDate, size: entriesQuerySnapshot.size }
},
(error) => {
return { date: entryDate, size: -1, error }
}
);
// add this promise to the queue
fetchSizePromises.push(thisEntrySizePromise)
}
// wait for all fetch operations and return their results
return Promise.all(fetchSizePromises);
})
.then((entryInfoResults) => {
// for each entry, log the result
entryInfoResults.forEach((entryInfo) => {
if (entryInfo.error) {
// this entry failed
console.log(`${entryInfo.date} has an unknown number of customers in its Entries subcollection due to an error`, entryInfo.error);
} else {
// got size successfully
console.log(`${entryInfo.date} has ${entryInfo.size} customers in its Entries subcollection`);
}
}
});
Using below code you can console every document id inside waterCanData collection. In your database you have only one document, then it will console your document id. (10042021)
firestore()
.collection('WaterCanData')
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(doc.id)
});
})

Firestore Collection Doesn't retrieve expected output

I have a react native function to to get all collection documents as follows
export const fetchAuctionItems = () => {
return firestore().collection('items').get();
};
When I'm accessing above function response not getting any documents instead that I'm getting following
Can anyone one help me to solve my problem, Thank you
collection.get() returns a a QuerySnapshot and this is the data you are seeing. You need to request the data from the QuerySnapshot, like so for example.
export const fetchAuctionItems = () => {
return firestore().collection('items')
.get()
.then(querySnapshot => querySnapshot
.docs
.map(d => ({
id: d.id,
...d.data(),
});
};
Read more about QuerySnapshot here

Cant use firebase reference data type to get subcollection

I am trying to leverage a reference data type from the profile document to access a subcollection on the referenced clan document.
leaveClan() {
console.log(this.getUser.displayName + " leaving " + this.getProfile);
console.log(this.getProfile.data().clan);
console.log(this.getProfile.data().clan.get().collection("members")
.doc(this.getUser.uid));
firebase
.firestore().
this.getProfile.data()
.clan
.get()
.collection("members")
.doc(this.getUser.uid)
.delete()
.then(() => {
firebase
.firestore()
.collection("profiles")
.doc(this.getUser.uid)
.update({
clan: null
});
});
},
Ok figured it out.
this.getProfile
.data()
.clan.get()
.then(snapshot => {
console.log(snapshot.data());
});
just .get() or whatever normal firebase operation you would do. The field with the reference is essentially the doc reference as well.
I am sure there is a better answer that explains why this works or the right terms but it works haha.

How to read a sub-collection's document fields from Firestore in react-native

Trying to read all sub collections from a document inside a root-level collection from firebase's Firestore in a react-native project. Not too sure which documentation to follow (web-can't do getCollections() /node?). Firebase is imported and I have successfully retrieved other data from firestore, but never have I been able to read sub collection data. This is not using the library react-native-firebase (Although I’ve tried with react-native-firebase and it has no documented solution to this either) Regardless, I've tried:
componentDidMount() {
firebase
.firestore()
.collection('users')
.doc(this.props.user.uid)
.getCollections('conversations')
.then(collections => {
collections.forEach(collection => {
alert(collection.id)
})
})
}
the above returns '_firebase.default.firestore().collection("users").doc(this.props.user.uid).getCollections' is undefined
also have tried:
componentDidMount() {
firebase
.firestore()
.collection("users")
.doc(this.props.user.uid)
.collection("conversations")
.get()
.then(collections => {
collections.forEach(collection => {
alert(JSON.stringify(collection)); //collection.id is can be read here
});
});
in the above, the collection id can be read, but how can the document fields be read? the above gives me cyclic structure errors.
alert(collection.data()) gives me [object Object]
alert(JSON.stringify(collection.data()) gives me cyclic structure errors
here is the firestore:
The practical application would be populating all conversations for a given user, and then all messages for a given conversation.
How Do I read data from all sub collections from Firestore in a react-native project?
To read the sub-collection document data what ultimately worked was:
_getConversation() {
firebase
.firestore()
.collection("users")
.doc(this.props.user.uid)
.collection("conversations")
.get()
.then(querySnapshot => {
querySnapshot.forEach(queryDocumentSnapshot => {
alert(queryDocumentSnapshot.get("members"));
});
})
.catch(err => {
alert(err);
});
}
and
_getMessages() {
firebase
.firestore()
.collection("users")
.doc(this.props.user.uid)
.collection("conversations")
.doc("some-document-id-here")
.collection("messages")
.get()
.then(querySnapshot => {
querySnapshot.forEach(queryDocumentSnapshot => {
alert(queryDocumentSnapshot.get("content"));
});
});
}
a deeper dive into documentation was indeed more helpful
Hi try with below
async _getUserDataFromFirestore() {
try {
const ref = firebase
.firestore()
.collection('user')
.doc(this.props.user.uid);
await ref.get().then(userData => {
console.log('User details of userID - ' + this.props.user.uid , userData.data());
});
} catch (err) {
console.log('Error while getting user data from firestore : ', err);
}
}
Add call this function in componentDidMount

Chaining Firebase Firestore documents/collections

So, I have a Firestore database group like so.
companies > acme-industries > items > []
OR
collection > document > collection > document
Would it be better to just store all items inside a base collection and then add a string value to each item that defines what company it goes too? Then just query the items collection for all items linked to that company?
I am trying to retrieve the items and run them through a forEach in my firebase function. I have tried two different approaches and watched multiple videos and still am not getting results.
First Attempt Code Block
This resulted in a 500 Server Error with no explanation returned.
const itemQuerySnapshot = db.collection('companies').doc(data.userData.company).collection('items').get();
const items: any = [];
itemQuerySnapshot.forEach((doc:any) => {
console.log('doc', doc.data());
items.push({
id: doc.id,
data: doc.data()
});
});
response.json(items);
Second Attempt Code Block
This resulted in the No Such Documents! being returned
const itemRef = db.collection('companies').doc(data.userData.company).collection('items');
itemRef.get().then((doc:any) => {
if(!doc.exists) {
response.send('No such documents!');
} else {
response.send('Document Data: '+ doc.data());
}
}).catch((err:any) => {
response.status(500).send(err);
});
I am expecting something like an array of all the items to be returned from this call. I'm completely new to Firebase Firestore, what am I missing here?
UPDATE
I replaced my code with a third attempt code block and I got success with the console.log(doc.data()). However, the items object still returns empty. Is this because it's returning before the for each is done? If so, how would you prevent that to ensure every item that should be returned is?
const items: any = [];
const userRef = db.collection("companies").doc(data.userData.company);
const itemsRef = userRef.collection("items");
itemsRef
.get()
.then((snapshot: any) => {
snapshot.forEach((doc: any) => {
console.log(doc.data());
items.push({
id: doc.id,
data: doc.data()
});
});
})
.catch((err: any) => {
response.status(500).send(err);
});
response.json(items);
How would you add one more document into the mix? Say you want to get a single item. How would you do that? The following always results in Item does not exist being returned from my function.
const companyRef = db.collection('companies').doc(data.userData.company);
const itemRef = companyRef.collection('items');
const item = itemRef.where('number', '==', itemSku).get();
I must be doing something incredibly wrong here because all the videos are telling me it's incredibly easy to fetch data from Firestore. But I have yet to see that.
get returns a Promise , the callback of then function will be called once the data ready from firestore .
the line response.json(items); will be called before the items array collected correctly.
you need to move this line inside the then callback
checkout this :
.then((snapshot: any) => {
snapshot.forEach((doc: any) => {
console.log(doc.data());
items.push({
id: doc.id,
data: doc.data()
});
});
response.json(items); //items ARRAY IS READY , YOU CAN SEND YOUR RESPONSE HERE
})

Resources