问题
Lets say I have two top level collection with users and stories. Now everytime a document from user gets update (only the values username
or photoUrl
), I want to update these properties on a document from the story collection.
One users doc could look like this (shortened):
{
username: 'blubber',
photoUrl: 'my/photo/path',
uid: 'usersUniqueId'
}
The story doc could look like this (shortened):
{
username: 'blubber',
photoUrl: 'my/photo/path',
uid: 'usersUniqueId',
sid: 'storiesUniqueId,
content: '...'
}
Now on the cloud functions part. I dont now how to query all documents from the stories collection that contains the users id. The code from now looks like this:
export const onUpdateUser = functions.firestore.document('/users/{userId}')
.onUpdate((change, context) => {
const before = change.before.data();
const after = change.after.data();
if(before.username !== after.username || before.photoURL !== after.photoURL) {
return admin.firestore().collection('/stories/')
.where(before.uid, '==', ***fetch the comparison***)
// do something
} else {
return null;
}
});
Can anyone help me out on this?
回答1:
Updated the code below. Pretty much had it. I added async await as it will make the code cleaner to follow, you would want to add in error handling etc.
export const onUpdateUser = functions.firestore.document('/users/{userId}')
.onUpdate(async (change, context) => {
const before = change.before.data();
const after = change.after.data();
if (before.username !== after.username || before.photoURL !== after.photoURL) {
return admin.firestore().collection('/stories/')
.where('uid', '==', before.uid).get().then(
result => {
if (result.size > 0) {
result.forEach(async doc => {
await doc.ref.update({
username: after.username,
photoUrl: after.photoUrl
})
})
}
return;
}
)
} else {
return null;
}
});
回答2:
I believe, this is what you are trying to achieve.
I just separated out the function call from its reference in the .onUpdate
call. Since you haven't explicitly stated, I have also assumed that you are going to update multiple docs in the stories
collection and for that, we are using batch
.
const onUpdateUser = functions
.firestore
.document('/users/{userID}')
.onUpdate(myFunc);
const myFunc = (change, context) => {
const before = change.before.data();
const after = change.after.data();
// Nothing changed, so exiting the cloud function early.
if (before.username === after.username
&& before.photoURL === after.photoURL) {
return Promise.resolve();
}
return admin
.firestore()
.collection('stories')
.where('uid', '==', before.uid)
.get()
.then((docs) => {
const batch = admin.firestore().batch();
docs.forEach((doc) => {
batch.set(doc.ref, {
username: after.username,
photoURL: after.photoURL,
}, {
// Merges the fields rather than replacing the
// whole document data
merge: true,
});
});
return batch.commit();
})
.catch(console.error);
};
来源:https://stackoverflow.com/questions/53278365/firebase-cloud-functions-make-queries-on-collection