bastifix
bastifix

Reputation: 483

Firebase Cloud Functions: Keeping things in sync

I have users and companies and want to store a company for each user and all of the users of each company in Firebase.

user={
  "id":"tjkdEnc3skdm2Jjknd"
  "name":"Adam",
  "street":"Sideway 4",
  "company":"dHend4sdkn25"
}

companies={
  "id":"dHend4sdkn25",
  "name":"Comp Ltd.",
  "members":[
      {
      "id":"tjkdEnc3skdm2Jjknd"
      "name":"Adam"
      },{
      "id":"dfjnUkJKB3sdn8n2kj"
      "name":"Berta"
      }
  ]
}

All explanations say that duplicate data is the best way to deal with and so I want to write some cloud functions to keep thigs in sync when editing on one of the sides. Basically I started with

exports.userChangedCompany = functions.firestore
.document('users/{userId}')
.onUpdate((change, context) => {
  const data = change.after.data();
  const previousData = change.before.data();

  if (data.company == previousData.company) {
    return null;
  }
   else{
    admin.firestore().doc('companies/'+data.company).set({ ... });
   } 
  });

to update the companies when a user changed the company. Unfortunately I haven't found any hint how to set the new company-data properly. Can someone please help me?

Upvotes: 0

Views: 295

Answers (1)

Dharmaraj
Dharmaraj

Reputation: 50830

It sounds like you just need to remove user from members array of old company and add in that array of new company. You just need IDs of both companies.

async function updateCompanies(userId, username, oldCompanyId, newCompanyId) {
  const companiesRef = await admin.firestore().collection("companies")
  const userObj = {id: userId, name: username}
  
  // Removing from old company and adding in new company
  await Promise.all([ 
    companiesRef.doc(oldCompanyId).update({members: admin.firestore.FieldValue.arrayRemove(userObj)}),
    companiesRef.doc(newCompanyId).update({members: admin.firestore.FieldValue.arrayUnion(userObj)})
  ])
  return true
}

You can just call this function in your cloud function. Just make sure you pass correct params. The reason why you need to pass the username as well is you have array of objects (members) and hence you need the complete object to add/remove using arrayUnion/arrayRemove.

Upvotes: 1

Related Questions