Javascript

How to update an array of objects with Firestore

27 September 2026 · 6 min read

How to update an array of objects with Firestore

Managing dynamic data structures is a cornerstone of modern application development, and when working with NoSQL databases like Firestore, understanding how to efficiently manipulate these structures is paramount. A common scenario developers encounter is the need to update an “array of objects” with Firestore. While Firestore excels at storing flexible, schema-less data, directly modifying individual elements within a complex object array can present unique challenges compared to simpler field updates. This post will delve into the intricacies of handling such operations, providing expert strategies and best practices to ensure your data remains consistent, scalable, and performant. We’ll explore various approaches, from client-side modifications to more robust transactional updates, ensuring you have the knowledge to select the most appropriate method for your specific application needs.

Understanding Firestore’s Approach to Arrays

Firestore, part of Google’s Firebase suite, treats arrays as a fundamental data type, but its capabilities for modifying elements within those arrays are somewhat limited, especially when dealing with complex objects. Unlike relational databases where you might update a specific row by its primary key, Firestore’s operations like arrayUnion() and arrayRemove() are designed primarily for adding or removing entire primitive values or exact object matches from an array field. This means if you have an array of objects, and you want to modify a property of just one object within that array, these direct array operators won’t suffice. You can add a new, complete object, or remove an existing, identical object, but not update one in place.

This limitation stems from Firestore’s document-oriented nature, where entire documents are typically read and written. When you consider how data modeling impacts performance and cost, understanding this behavior is critical. For instance, attempting to update a nested field within an array object directly is not a supported operation. Developers must therefore employ strategic workarounds to maintain data integrity and efficiently manage their Firestore array fields. This often involves fetching the document, manipulating the array data in application memory, and then saving the entire modified array back to the document, a pattern known as “read-modify-write.”

The choice of strategy significantly impacts application performance and development complexity. For smaller, less frequently updated arrays, the read-modify-write approach might be straightforward. However, for large arrays or high-concurrency scenarios, this method can lead to race conditions and increased costs due to multiple document reads and writes. Evaluating your specific use case, including array size, update frequency, and concurrency requirements, is essential for effective data modeling in Firestore. As noted by the Firebase team, “Choose the right data model to minimize reads and writes, and scale your application effortlessly.”

Strategies for Modifying Arrays of Objects in Firestore

Strategy 1: Reading, Modifying, and Rewriting the Entire Array

One of the most common and straightforward ways to update an array of objects in Firestore is to implement the read-modify-write pattern. This involves first reading the document containing the array, then performing the necessary modifications to the array in your application’s memory, and finally, writing the entire updated array back to Firestore. For example, if you have a document representing a user, and it contains an array of {productId: 'X', quantity: 2} objects for their shopping cart, to update the quantity of a specific product, you would fetch the user document, find the specific product object in the cart array, update its quantity, and then save the entire cart array back to the user document.

This approach offers simplicity and direct control over the array’s contents. It’s particularly effective for smaller arrays or scenarios with low concurrency, where the likelihood of multiple clients attempting to modify the same array simultaneously is minimal. However, it’s crucial to acknowledge the potential for race conditions. If two users simultaneously try to update the same array using this method without proper safeguards, one user’s changes might overwrite the other’s, leading to data loss. This is where client-side modification needs to be paired with robust concurrency control mechanisms, which we will discuss further.

While conceptually simple, repeatedly reading and writing entire arrays, especially large ones, can also impact performance and cost. Each time you update a single element, the entire array field counts as a write operation. This can become inefficient for applications with frequent updates to individual array elements. Developers must weigh the simplicity of this method against the potential performance and cost implications for their specific document updates workload.

Strategy 2: Leveraging Subcollections for Individual Object Management

For applications requiring more granular control, greater scalability, or frequent updates to individual elements within an array, modeling array elements as documents in a subcollection offers a powerful alternative. Instead of storing an array of objects directly within a parent document, each object can become its own document within a subcollection related to the parent document. For example, a “User” document could have a “FavoriteProducts” subcollection, where each favorite product (e.g., {productId: 'X', addedDate: 'Y'}) is a separate document within that subcollection.

This approach transforms array elements into first-class Firestore documents, allowing for individual read, update, and delete operations without affecting other elements or the parent document. This significantly reduces the risk of race conditions and provides more efficient updates for single items. When you need to update a property of a specific favorite product, you simply target that product’s document within the subcollection, performing a direct field update. This is particularly beneficial for large arrays that are frequently modified or when you need to query specific attributes of array elements without fetching the entire parent document.

While leveraging Firestore subcollections enhances scalable data structures and provides fine-grained control, it also introduces a slight increase in complexity in terms of data modeling and querying. You’ll need to manage references to subcollection documents and potentially perform additional queries to retrieve all “array elements.” However, for scenarios demanding high concurrency, efficient individual item updates, or when array elements themselves grow complex and benefit from independent lifecycle management, this strategy is often the superior choice for robust data modeling.

Infographic: Visualizing Firestore Array Update Strategies
Implementing the Read-Modify-Write Pattern Safely -------------------------------------------------

When choosing the read-modify-write pattern for document updates involving arrays of objects, preventing race conditions is paramount Question & Answer :

I’m currently trying Firestore, and I’m stuck at something very simple: “updating an array (aka a subdocument)”.

My DB structure is super simple. For example:

proprietary: "John Doe", sharedWith: [ {who: "<a class="__cf_email__" data-cfemail="9ff9f6edecebdfebfaecebb1fcf0f2" href="/cdn-cgi/l/email-protection">[email protected]</a>", when:timestamp}, {who: "<a class="__cf_email__" data-cfemail="f7969998839f9285b783928483d994989a" href="/cdn-cgi/l/email-protection">[email protected]</a>", when:timestamp}, ], 

I’m trying (without success) to push new records into shareWith array of objects.

I’ve tried:

// With SET firebase.firestore() .collection('proprietary') .doc(docID) .set( { sharedWith: [{ who: "<a class="__cf_email__" data-cfemail="60140809120420140513144e030f0d" href="/cdn-cgi/l/email-protection">[email protected]</a>", when: new Date() }] }, { merge: true } ) // With UPDATE firebase.firestore() .collection('proprietary') .doc(docID) .update({ sharedWith: [{ who: "<a class="__cf_email__" data-cfemail="6f1b07061d0b2f1b0a1c1b410c0002" href="/cdn-cgi/l/email-protection">[email protected]</a>", when: new Date() }] }) 

None works. These queries overwrite my array.

The answer might be simple, but I could’nt find it…

Firestore now has two functions that allow you to update an array without re-writing the entire thing.

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

Update elements in an array

If your document contains an array field, you can use arrayUnion() and arrayRemove() to add and remove elements. arrayUnion() adds elements to an array but only elements not already present. arrayRemove() removes all instances of each given element.