Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot update/delete Firestore field with "period" in the name

I'm trying to update/delete a fields in a Firestore document, but the fields that have a "period" in the name seem to be silently failing when trying to update/delete them. The reason I have periods is that I'm using URLs as the keys in the object, I feel this is a semi-common use case.

Example:

First create the document (this works fine)

db.collection("data").doc("temp").set({
  helloworld: {
      key1: 'foo'
  },
  hello.world: {
      key1: 'bar'
  }
})

If you try to delete the element without the period, it works fine.

db.collection("data").doc("temp").update({
    helloworld: firebase.firestore.FieldValue.delete()
})
// Value is Deleted

If you try to delete the element with the period, it doesn't do anything.

db.collection("data").doc("temp").update({
    hello.world: firebase.firestore.FieldValue.delete()
})
// Nothing Happens!

I've also tried

let u = {}
u['hello.world'] = firebase.firestore.FieldValue.delete()
db.collection("data").doc("temp").update(u)
// Nothing Happens!

Is this a bug? Are periods in field names supported? It seems strange I can create the element but not delete it.

like image 771
Sandeep Dinesh Avatar asked Dec 13 '17 20:12

Sandeep Dinesh


4 Answers

The update operation is reading hello.world as a dot-separated path to a field called word that is nested like this:

{
  hello: {
   world: "Some value"
  }
}

If you have a field with a dot in the name you need to use FieldPath to refer to it literally in an update: https://firebase.google.com/docs/reference/js/firebase.firestore.FieldPath

So this is what you want:

doc.update(
  firebase.firestore.FieldPath("hello.world"), 
  firebase.firestore.FieldValue.delete());
like image 108
Sam Stern Avatar answered Nov 05 '22 07:11

Sam Stern


None of the other answers worked for me, the closest one had a new() keyword missing, here is what worked for me

let fpath = new firestore.firestore.FieldPath(`hello.${world}`);
doc.update(
    fpath,
    firestore.firestore.FieldValue.delete()
);
like image 40
ishandutta2007 Avatar answered Nov 05 '22 07:11

ishandutta2007


You need to wrap it in quotes when you use periods in the name on an update or delete like:

db.collection("data").doc("temp").update({
  "hello.world": firebase.firestore.FieldValue.delete()
})

or for dynamic names:

[`hello.${world}`]: firebase.firestore.FieldValue.delete()
like image 5
J Livengood Avatar answered Nov 05 '22 07:11

J Livengood


I found a workaround if you are using dynamic keys and J Livengood's solution doesn't work for you. You can use the "set" method with "merge: true" to selectively set the key with the delete value.

var dynamicKey = "hello.world"    

// ES6
db.collection("data").doc("temp").set({ 
    [dynamicKey]: firebase.firestore.FieldValue.delete()
}, { merge: true })


// ES5
var obj = {}
obj[dynamicKey] = firebase.firestore.FieldValue.delete()
db.collection("data").doc("temp").set(obj, { merge: true })
like image 2
Sandeep Dinesh Avatar answered Nov 05 '22 07:11

Sandeep Dinesh