Firestore referenceI fixed most of my other issues but what I've been stuck on for today is figuring how to get a user to have multiple posts under the same uid.
Each post is under the, Post:"", field and everything I tried didn't work. Any tips or solutions?
const textToSave = inputTextField.value;
docRef.collection("ask").doc(user.uid).add({
Post: textToSave
}).then(function () {
console.log('saved')
}).catch(function (error) {
console.log('error');
})
You are trying to add() a document to a document, which is not valid. Documents can only be added to collections. You could do something like:
docRef.collection("ask")
.doc(user.uid)
.collection("posts")
.add({Post: textToSave})
or you could store multiple posts in an array inside the same doc, something like:
docRef.collection("ask")
.doc(user.uid)
.update({
posts: firebase.firestore.FieldValue.arrayUnion({Post: textToSave})
})
Related
created() {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.userID = user.uid;
console.log(this.userID);
} else {
console.log('User is not logged in.');
this.$router.push('/login');
}
});
},
data() {
return {
pantry: [],
userID: '',
};
},
methods: {
getCategoryDataFromFirebase() {
const db = firebase.firestore();
db.collectionGroup("pantry")
.where("UserID", "==", this.userID)
.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
this.pantry.push(doc.data());
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
},
},
};
I am attempting to do a Collection Group Query where I grab all of the listings in my firestore database that are associated with the user ID that created them. I am able to get the user ID on the created hook and store it in my this.userID. I want to then use that ID on my getCategoryDataFromFirebase function to do the collection group query.
It's recommended to create the collection group query and get the SDK error back from firebase in the console, then use the attached link in the console to create the appropriate rules automatically instead of manually which I did. Now I am thinking that I must not be referencing the group correctly because I am unable to get any data back from my firestore. I have tried to create the group by the main "pantry" but I am thinking that I would possible need to drill down further into the database or to set up the query another way. I would appreciate any guidance that could be given. I have attached the view of my firestore as well for reference. I am attempting to get all of the userIDs in each category i.e. fruits, vegetables, etc.
When you use db.collectionGroup("pantry") you are reading from all collections named pantry. In your code that is only a single top-level collections.
If you want to read from all Vegetables collections, you need to query db.collectionGroup("Vegetables").
I have a flatlist which displays all the posts of users that the current user is following. This is normal in instagram, twitter, all social networks etc.
I want to display them chronologically, but it is not working.
The code works like this:
I query Firestore for the current user's posts
I have a list of UID's of ever user the current user is following
I query Firestore for the posts of whoever the current user is following
This returns all the posts I want
The posts are in blocks. Ex, current user's posts are added to the array. Then user1 current user is following's posts get added. Then user2's posts get added. Etc.
I attempt to run a .sort function provided by Javascript to order the posts chronologically
Here is the code for it (removed the doc fields as they are not important, except date_created):
getCollection = async (querySnapshot) => {
const followingPosts = [];
await Firebase.firestore() <----------------------- Get current users posts
.collection('globalPosts')
.where("uid", "==", Firebase.auth().currentUser.uid)
.onSnapshot(function(query) {
query.forEach((doc) => {
const {
....other fields
date_created
....other fields
} = doc.data();
followingPosts.push({
....other fields
date_created
....other fields
});
})
});
querySnapshot.forEach(async (res) => {
await Firebase.firestore() <-------------- get following users posts, uid after uid
.collection('globalPosts')
.where("uid", "==", res.data().uid)
.onSnapshot(function(query) {
query.forEach((doc) => {
const {
....
date_created
....
} = doc.data();
followingPosts.push({
....other fields
date_created
....other fields
});
})
});
});
followingPosts.sort(function(a,b){ <-------- How I try to sort the posts by date created
return a.date_created.toDate() - b.date_created.toDate()
})
this.setState({
followingPosts,
isLoading: false,
});
}
Few notes:
The posts are fetching correctly (only the people that current user is following's posts show up)
The reason I am doing date_created.toDate() is because firestore timestamp objects are in nanoseconds and milliseconds. Whether I have date_created.toDate() or just date_created, it doesn't work.
I am aware that I can query firestore and order by date_created, descending in the query. But since the posts are being queried sequentially, this only orders the individual blocks of posts, not the entire array
I have tried putting the followerPosts.sort function INSIDE the query snapshot, after the for each. Not working either:
querySnapshot.forEach(async (res) => {
await Firebase.firestore()
.collection('globalPosts')
.where("uid", "==", res.data().uid)
.onSnapshot(function(query) {
query.forEach((doc) => {
const {
....other fields
date_created
....other fields
} = doc.data();
followingPosts.push({
....other fields
date_created
....other fields
});
})
});
followingPosts.sort(function(a,b){
return a.date_created.toDate() - b.date_created.toDate()
})
});
EDIT: more information on date_created:
Upon creation (Adding a new post to firestore), date_created is initialized like this:
date_created: new Date()
Within firestore, the above method of initializing date created looks like this:
When I console log the date_created, I am returned a firestore timestamp object:
t {
"nanoseconds": 14000000,
"seconds": 1610413574,
}
This is unusable for my purposes, so I convert this timestamp object using .toDate() when I pass the data to the flatlist:
<FeedCellClass
... other fields
date_created={item.date_created.toDate()}
/>
.toDate() converts it to this, which I can use for my purposes:
2021-01-12T01:06:14.014Z
Let me know how to solve this issue.
I solved my problem - I was sorting in the wrong place. Here is the solution:
querySnapshot.forEach(async (res) => {
await Firebase.firestore()
.collection('globalPosts')
.where("uid", "==", res.data().uid)
.onSnapshot(function(query) {
query.forEach((doc) => {
const {
...
date_created
} = doc.data();
followingPosts.push({
...
date_created
});
}) <----------- I put it in the on snapshot, instead of after.
followingPosts.sort(function(a,b){
return b.date_created.toDate() - a.date_created.toDate()
})
});
});
Thanks everyone
I'm in the process of writing an API using firebase functions: api is written in javascript.
In my firestore db, I have a user document that contains some nested fields. For example, my user doc has a field that looks roughly like this:
profile
education
education1 --> degree: doc ref, date: timestamp, school: doc ref
education2 --> degree: doc ref, date: timestamp, school: doc ref
I cannot for the life of me access the degree object and get the properties out of it. Each user could have multiple education entries (for example, people who hold multiple degrees). I can't step into those education# maps and access the fields inside the document they are referring to.
You didn't give a lot of details on your exact data model: which collection, which document, etc...
However, since in your comment above you say that "profile is a map, education is a map that lives inside of profile, and education items are also maps that live inside of education" the following should do the trick
var docRef = firestore.collection('collectionId').doc('docID');
docRef
.get()
.then(doc => {
if (doc.exists) {
const educationObj = doc.data().profile.education;
const promises = [];
Object.keys(educationObj).forEach(key => {
promises.push(firestore.doc(educationObj[key].degree.path).get());
});
return Promise.all(promises);
} else {
// doc.data() will be undefined in this case
console.log('No such document!');
throw new Error('no doc');
}
})
.then(results => {
results.forEach(r => {
console.log(r.data());
});
})
.catch(error => {
console.log('Error getting document:', error);
});
The degree property contains a DocumentReference, therefore you need use the path property in order to get the corresponding document.
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);
})
I am creating an app where people can read messages and in firestore, once they have read a message it adds the user's uid (who read it) to the specific doc, like so:
hasread
userId -> uid
What I am trying to do, is count the amount of docs that do not have the user's uid and return that number.
const usrId = firebase.auth().currentUser.uid;
const countNewAnnounce = this.announce
.where('hasread.userId', '!=', usrId)
.get()
.then(snapshot => {
console.log('size', snapshot.size);
})
.catch(err => {
console.log('Error getting documents', err);
});
The snapshot.size will always return the total amount of docs, so somehow the where is not working correctly or I am not using it correctly (probably the last).