1

I have objects that pretty much look like this:

{
  ...
  someArray: [
    {
      id: 1548,
      amount: 153,
      done: 0
    }
  ]
  ...
}

As these objects can become quite large, I can't just use set everytime I'm updating them, as sending 100kB everytime I need to update the document isn't an option.

In order to solve this, I decided to use update with what's called the "dots notation", example usage being :

update({
  'a.b.c': true
})

Source: Difference between set with {merge: true} and update

So I decided to give it a try and it worked like a charm for "normal" nested fields, but I can't find how I can do this for objects that are nested inside arrays.

What I tried was this:

update({
  'a.someArray.0.done': 153
})
update({
  'a.someArray[0].done': 153
})

But both of these just erased the object and replaced it by the patch, meaning that the dots notation wasn't recognized properly.

How can I solve this? Is there a solution for this kind of approach or should I just refactor it using a subcollection?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Supamiu
  • 8,501
  • 7
  • 42
  • 76
  • Did you find any solution to this? – Mangesh May 21 '20 at 18:01
  • Not really, I tried to use a cloud function to make document fetch faster, but it wasn't, so for now I just reduced the size of the document and I'm still using SET instead of UPDATE. – Supamiu May 22 '20 at 08:10
  • Yeah. Another workaround would be to `get` the document and `update` just the array instead of whole document `set`. – Mangesh May 22 '20 at 15:37

1 Answers1

0

I believe this could be what you are looking for:

var washingtonRef = db.collection("cities").doc("DC");

// Atomically add a new region to the "regions" array field.
washingtonRef.update({
    regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia")
});

https://firebase.google.com/docs/firestore/manage-data/add-data#update_elements_in_an_array

danwillm
  • 469
  • 3
  • 17
  • The issue with this is that this documentation only shows how to add or remove items to arrays, not how to update the said items. – Supamiu Sep 27 '19 at 18:08
  • @Supamiu whats stopping you from reading and then writing the document? You'll be charged the same amount of reads and writes doing it this way. Is it due to downloaded size? – danwillm Sep 27 '19 at 18:10
  • Yes, because this document has to be able to be updated quite often, like every second in worst cases. Using a connection that is < 100kB/s upload, this is barely manageable and uses all the bandwidth. Also sending a 100kB document to update a number inside a nested object feels like overkill. – Supamiu Sep 27 '19 at 18:12
  • @Supamiu I see, perhaps storing it as subcollections may be a better option? – danwillm Sep 27 '19 at 18:14
  • I'd like to avoid that, which is why I'm asking here :) but seems like I'll have to. – Supamiu Sep 27 '19 at 18:16
  • @Supamiu haha, what would be the disadvantages of using a subcollection? – danwillm Sep 27 '19 at 18:38
  • Having to map them to arrays on runtime, and back to collection when saving them – Supamiu Sep 27 '19 at 18:38
  • @Supamiu how is an array going to be >100kb? – danwillm Sep 27 '19 at 18:40
  • What I mean is that this is a full object, with plenty of other fields and another array like this one. The application uses a precise data model and I need to change all my persistence layer so it maps subcollections to arrays and the other way around when saving, so I can save just one item inside the subcollection instead of the whole collections. – Supamiu Sep 27 '19 at 18:43
  • @Supamiu I see, have you tried using maps in the firestore collection, or is that what you are using at the moment? Furthermore, are you pulling everything already from the db? – danwillm Sep 27 '19 at 18:53
  • Even if you are using subcollections you can always have a lot of options of having good performance, regarding the way you query, like using StructuredQueries - https://cloud.google.com/firestore/docs/reference/rest/v1/StructuredQuery ; or using transactions or batch writes - https://cloud.google.com/firestore/docs/manage-data/transactions#batched-writes – Andrei Tigau Oct 10 '19 at 08:54