Reputation: 8801
I am developing a web app on Firebase/firestore, in which users can sign in and write their own posts. The data are stored in the following way:
-User information are stored as under collection('user').doc('uid').
-Information about posts the user has written are stored in collection('post').doc('postid'), and the doc has 'userinfo' and 'uid' fields. The 'userinfo' field contains exact copy of what is stored in 'uid' doc, just in object format.
Here are the operations that I want to do:
When the user changes the data, the changes are reflected in the document.
Look for the all the posts that the user has written based on 'uid' data, and then update userinfo in those data.
The last part is tricky for me. The Firebase documentations cover situations where the references are pretty much static, i.e. you know the exact path to write/update. What I am trying to do is look for a set of documents that is not necessarily static, and then update each of them.
Here is the code I wrote for this effort. The first part works without any problem. Of course, the second part doesn't work. :) What would be the code to do the do the second part?
const update = () => {
//This part is for updating user information. This works without any problem.
firebase.firestore().collection('user').doc(user.uid).update({
username: username1,
nickname: nickname1,
intro: intro1
})
.then(()=>{
//This part is for updating all of the document that the user has written based on 'uid' value. This doesn't work.
//Below code is probably way off, but it shows where I am going and what I am trying to do.
firebase.firestore().collection('post').where('uid','==',user.uid).get()
.then((querysnapshot)=>{
querysnapshot.forEach((doc)=>{
let ref=firebase.firestore().collection('post').doc(doc.id);
ref.update({
userinfo: {nickname:nickname1,username:username1,intro:intro1}
})
})
})
}).then(()=>{
alert("Successfully updated!");
window.location.href='/'+username1;
}).catch((error)=>{
alert("Error!");
})
}
Thanks a lot in advance!
Upvotes: 0
Views: 315
Reputation: 773
What's the error that you get running this code? It seems on the right track for me.
But despite that, here are some suggestions to deal with this kind of update:
Don't do the second part on the client side, do it on the server side with a Firestore Trigger (create a onUpdate trigger in the user collection in your case): https://firebase.google.com/docs/functions/firestore-events.
You don't need to recreate the DocumentReference after getting the query result, the docs returned already have a .ref that you can call .ref.update() directly.
EDIT: If you want to keep your original code (updating on client side), the problem of the navigation occurring before all the updates to conclude is because ref.update() returns a promise.
So the update queue is asynchronous being performed on database when the client navigates away.
To solve this, I would use a Promise.all() to wait all updates being completed.
firebase.firestore().collection('post').where('uid','==',user.uid).get()
.then((querysnapshot)=>{
const promises = [];
querysnapshot.forEach((doc)=>{
promises.push(doc.ref.update({
userinfo: {nickname:nickname1,username:username1,intro:intro1}
});
});
Promise.all(promises).then(()=>{window.location.href='/'+username1;});
});
Or using the await syntax (I think it's easier to maintain and understand):
const querysnapshot = await firebase.firestore().collection('post').where('uid','==',user.uid).get();
const promises = [];
querysnapshot.forEach((doc)=>{
promises.push(doc.ref.update({
userinfo: {nickname:nickname1,username:username1,intro:intro1}
});
});
await Promise.all(promises);
window.location.href='/'+username1;
Upvotes: 1