Home > Software engineering >  Firestore - Does the dot notation work with set()?
Firestore - Does the dot notation work with set()?

Time:12-02

I am trying to run this code:

function updateUserLimitations(userId, limitations, batchOrTransaction = undefined) {
  const userLimitationsRef = firestore
    .collection("users")
    .doc(userId)
    .collection("limitations")
    .doc("userLimitations");

  if (batchOrTransaction) {
    return batchOrTransaction.set(
      userLimitationsRef,
      limitations,
      { merge: true }
    );
  }

  return userLimitationsRef.set(limitations, { merge: true });
}

updateUserLimitations(userId, { "messages.totalMessages": admin.firestore.FieldValue.increment(1) });

But...

Instead of getting this doc data in my db:

{ // Doc data
   messages: {
      initialDate: timestamp, // Date of the first message (I need to preserve it),
      totalMessages: 20,
   },
}

I am getting:

{
   ...other doc data...,
   messages.totalMessages: 20,
}

I need the set with the merge option, because I am updating and creating if the doc doesn't exist....

Any ideas? Am I doing something wrong here?

CodePudding user response:

You can use an object for "setting" nested data:

{
  messages: {
    totalMessages: 20,
  }
}

The "dot" notation is for applying updates to nested data.

CodePudding user response:

If you need only to update, then use the update() function instead of set(). So please change the following line of code:

return userLimitationsRef.set(limitations, { merge: true });

To:

return userLimitationsRef.update(limitations);

And your:

updateUserLimitations(userId, { "messages.totalMessages": admin.firestore.FieldValue.increment(1) });

It will work as expected. If you want to add if it doesn't exist, then you should indeed use the set() function.

CodePudding user response:

With my current implementation

function updateUserLimitations(userId, limitations, batchOrTransaction = undefined) {
  const userLimitationsRef = firestore
    .collection("users")
    .doc(userId)
    .collection("limitations")
    .doc("userLimitations");

  if (batchOrTransaction) {
    return batchOrTransaction.set(
      userLimitationsRef,
      limitations,
      { merge: true }
    );
  }

  return userLimitationsRef.set(limitations, { merge: true });
}

I can deeply update the document messages field too, as follows:

updateUserLimitations(
   userId,
   { 
      messages: {
        totalMessages: admin.firestore.FieldValue.increment(1),
      }
   }
);

It preserves all the previous existing object fields and updates the specific one.

{ // Doc data
  messages: {
    initialDate: timestamp, // PRESERVED!
    totalMessages: 21,
  },
}
  • Related