5

I want to update fields in nested objects in my Cloud Firestore by using dot notation. But those fields referenced by the dot notation are variables.

How can I do that?

Documentation
// To update age and favorite color:
db.collection("users").doc("frank").update({
    "age": 13,
    "favorites.color": "Red"
})

But what if I need to make favorites.color a variable?

const attributes = [ 'jobs', 'schools', 'favorites', ];
const values = [ 'food', 'song', 'color', ];
const variableData = [attributes[2]].[values[2]]; // 'favorites.color'

Can I do:

db.collection("users").doc("frank").update({
  "age": 13,
  "[attributes[2]].[values[2]]": "Red"
})

How, exactly, would this work?

Edit:

Failed attempts

I tried:

db.collection("users").doc("frank").update({
  "age": 13,
  `${[attributes[2]]}.${[values[2]]}`: "Red"
})

and got the following error:

Parsing error: Unexpected token

Same error also occurs when trying

`"${[attributes[2]]}.${[values[2]]}"`: "Red"

(Thinking that Firebase needs the quotation marks to parse the syntax.)

Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207

1 Answers1

7

The key thing you are missing is that when you are using computed property names, you need to wrap the expression in []. For example, you should write it as the following:

db.collection("users").doc("frank").update({
  "age": 13,
  [`${attributes[2]}.${values[2]}`]: "Red"
})

Runnable example:

const attributes = [ 'jobs', 'schools', 'favorites', ];
const values = [ 'food', 'song', 'color', ];

console.log({
  age: 13,
  [`${attributes[2]}.${values[2]}`]: 'red'
})

NOTE: Quotes do not matter when writing out keys in javascript. We only use backticks here because we want the each of the values ("favorite", "color") to be joined together by a dot.

Kobe
  • 6,226
  • 1
  • 14
  • 35
  • 1
    Using this I'm getting literally the dot as the field name and not the nested object dot notation. Meaning the field is called "favorites.color" and not favorites object with nested key of color being the value of red. – Mr.Drew Nov 10 '21 at 04:19
  • I'm also using a transaction.set() with merge options to true, if that makes any difference. – Mr.Drew Nov 10 '21 at 04:19
  • @Mr.Drew Sorry, I don't know anything about firebase, this answer was to address the usage of computed property names in an object. – Kobe Nov 10 '21 at 09:09
  • Yes, but the original question directly asks about Firestore. Was this solution tested on the platform before it was accepted? – Mr.Drew Nov 15 '21 at 16:40
  • @Mr.Drew You're using an API that is written in JavaScript, so I don't see why this code would not produce the same output elsewhere. If you have a question, raise a separate one [here](https://stackoverflow.com/questions/ask) – Kobe Nov 16 '21 at 08:26
  • I'm sorry for my confusion. I think I copy and pasted your first example and not the runnable code block one. I tried to submit a slight edit, but the edit queue is full. However, yes the example does work as intended. Thank you. The first example code is just missing a closing curly brace for the attributes array access. – Mr.Drew Jan 05 '22 at 22:44
  • 1
    @Mr.Drew you're right, edited it in now! Yeah I was quite confused as to what the issue was, but at least it's resolved now ;) – Kobe Jan 06 '22 at 11:34