Kevin Renskers
Kevin Renskers

Reputation: 5940

Firebase Cloud Function to keep user objects within documents up to date

I am using Firestore to store collections of Tasks and Users. The Task document can contain a map of users with a role, something like this:

{
  "title": "Task",
  "content": "Do this task",
  "members": {
    "ABC": {
      "role": "roleA",
      "user": {
        "diplayName": "Kevin",
        "email": "xxx",
        "photoURL": "xxx"
      }
    },
    "XYZ": {
      "role": "roleB",
      "user": {
        "diplayName": "Steve",
        "email": "xxx",
        "photoURL": "xxx"
      }
    }
  }
}

(where "ABC" and "XYZ" are the user id's)

I am storing a copy of the user objects there instead of just the ID, so that I have all the data that I need in 1 query, ready to use in the app.

Now, what I need to do is make sure that if one of the user objects in the top level Users collection is updated, to find all Tasks that have this user as a member, and then update that user object in that map.

I have most of the parts figured out, like listening to User changes, and finding Tasks with that User as a member. But now I need to actually update the Task and that's where I am hitting a roadblock. The Task doc doesn't have a set function, and I can't find in the docs how to actually update it like this.

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp();

const db = admin.firestore();

exports.updateUser = functions.firestore.document('users/{userId}').onUpdate((change, context) => {
  const user = change.after.data();
  const userId = context.params.userId;

  const query = db.collection('tasks').where(`members.${userId}.role`, '>', '');

  return query.get().then((snapshot) => {
    snapshot.forEach((doc) => {
      let members = doc.data().members
      members[userId].user = user

      doc.set({members: members}).then(writeResult => {
        console.log(`Document written at: ${writeResult.writeTime.toDate()}`);
      });
    });
  })
  .catch((err) => {
    console.log('Error getting documents', err);
  });
});

Upvotes: 1

Views: 144

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317760

Your doc is a QueryDocumentSnapshot type object. You can use its ref property to get DocumentReference for that document, then use that reference's set() method to modify its contents.

Upvotes: 2

Related Questions