1
votes

I have the following Firestore set up:

  • Users / uid / following / followingPersonUid /
  • Users / uid / followers / followerPersonUid /

So if User A would follow User B then User A would get added to the followers sub collection of User B also User B will get added to the Following Subcollection of User A

But let's say User A updates his profile info( name, photo, userName, etc. ). Then his user doc will change in his document but this needs to change everywhere wherever he is a follower in the Followers sub-collection of other users like User B or E & F.

Can this be done through cloud functions? I have created an onCreate() trigger for cloud functions but the function doesn't know the list of other users(uids) where he is a follower so I can't apply this change wherever it's needed.

This is my function in Firebase CLI, This is a firestore .onUpdate() trigger. I ve commented the place at which I am stuck

export const onUserDocUpdate = functions.region('asia- 
east2').firestore.document
('Users/{userId}').onUpdate((change, context) => {
const upDatedUserData = change.after.data()

const newName = upDatedUserData?.name
const profilePhotoChosen = upDatedUserData?.profilePhotoChosen
const updatersUserId = upDatedUserData?.uid
const newUserName = upDatedUserData?.userName

//This is where I am stuck, I have the updated document info but how do
//I find the other documents at firestore that needs updation with this 
//updated information of the user
    return admin.firestore()
    .collection('Users').doc('{followeeUserId}')
    .collection('Followers').doc(updatersUserId)
    .set({
    name: newName, 
    userName: newUserName,
    profilePhotoChosen: profilePhotoChosen,
    uid: updatersUserId
  })

})

Should I use a callable function instead wherein the client can send a list of following userIds that need to be updated.

1
Would that list be in the user's own following subcollection? Either way: it's probably easier to help if we see the minimal code that reproduces where are stuck.Frank van Puffelen
Hi Frank, I have added the code to show where I am stuck...Anudeep Ananth

1 Answers

1
votes

As far as I understand, a user updates their profile, and you then also want to update that profile in all their follower's data. Since you keep both followers and followees, you should be able to just read the subcollection of the user who triggered the cloud function:

export const onUserDocUpdate = functions.region('asia- 
east2').firestore.document
('Users/{userId}').onUpdate((change, context) => {
  const upDatedUserData = change.after.data()

  const newName = upDatedUserData?.name
  const profilePhotoChosen = upDatedUserData?.profilePhotoChosen
  const updatersUserId = upDatedUserData?.uid
  const newUserName = upDatedUserData?.userName

  const userDoc = change.after.ref.parent; // the user doc that triggered the function
  const followerColl = userDoc.collection("Followers");

  return followerColl.get().then((querySnapshot) => {
    const promises = querySnapshot.documents.map((doc) => {
      const followerUID = doc.id;
      return admin.firestore()
        .collection('Users').doc(followerUID)
        .collection('Followees').doc(updatersUserId)
        .set({
          name: newName, 
          userName: newUserName,
          profilePhotoChosen: profilePhotoChosen,
          uid: updatersUserId
        })
    });
    return Promise.all(promises);
  });
})

It could be that I have some typos/syntax error in there, but the semantics should be pretty solid. The biggest thing I wasn't sure of is the follower/followee logic you maintain, so I used the collection names as they make most sense to me, which could be inverted from yours.