Firebase cloud function firestore array union
Asked Answered
B

2

9

I'm unable to get the array union or increment to work properly in firebase cloud functions.

return docRef.update({

  object: {
    count: admin.firestore.FieldValue.increment(1),
    list: admin.firestore.FieldValue.arrayUnion({
      space_id: newData.date_id,
      user: {
        displayName: "john doe"
      }
    })
  }

When the function runs, it simply overwrites the existing data in the list array and the count is always set to 1 even though it currently exists and is of number type.

Bogan answered 7/4, 2019 at 13:33 Comment(6)
Can you share your document data model? Do you have an object field in your document? In addition, if I am not mistaking, arrayUnion doesn't work with nested arrays.Telemetry
Yes there is an object field and the updates work just not as expected. It will just override the existing data in the array instead up appending the new data. The increment doesn't work either and always sets to 1. If it were a nested array issue I should see something like this in the logs. Unhandled Rejection (FirebaseError): Function FieldValue.arrayUnion() called with invalid data. Nested arrays are not supportedBogan
Can you add screenshots to your question of the document before and after the update?Demigod
FYI, I've just tried with the JavaScript SDK from a web page. The arrayUnion seems to work, but not the increment within the object map. If you put another count field (e.g. count1) outside of the object the increment works.Telemetry
Did the arrayUnion work with an object or just a simple string? Can you post the code you just tested with?Bogan
@Bogan See my answer below. Actually I was wrong: arrayUnion in the object does not work, it overwrites the existing data.Telemetry
T
3

Following you comment, here is below the HTML code I tried. Note that it is not Cloud Function code (which uses the Admin SDK) but some JavaScript code using the JavaScript SDK. But most probably the Admin SDK has the same behavior.

To try it do as follows:

  1. Create a collection testSO in Firestore and a doc with ID doc1 and one dummy field.
  2. Save this HTML page on your computer and open it in browser.
  3. Then change the values and reload the page in the browser for experimenting the behavior

You will see that both arrayUnion and increment work when used with an array of strings for arrayUnion (field array1) and a number for increment (field count1) but not with the compounded object.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>

    <script src="https://www.gstatic.com/firebasejs/5.9.3/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.9.3/firebase-database.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.9.3/firebase-auth.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.9.3/firebase-functions.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.9.3/firebase-firestore.js"></script>
      </head>

  <body>
    <script>
      // Initialize Firebase
      var config = {
        apiKey: 'xxxxxxxxxxx',
        authDomain: 'xxxxxxxxxxx',
        databaseURL: 'xxxxxxxxxxx',
        projectId: 'xxxxxxxxxxx'
      };

      firebase.initializeApp(config);

      var db = firebase.firestore();

      db.doc('testSO/doc1').update({
        count1: firebase.firestore.FieldValue.increment(1),
        array1: firebase.firestore.FieldValue.arrayUnion('arrayItem'),
        object: {
          count: firebase.firestore.FieldValue.increment(1),
          list: firebase.firestore.FieldValue.arrayUnion({
            space_id: 'spaceNbr',
            user: {
              displayName: 'john doe'
            }
          })
        }
      });
    </script>
  </body>
</html>
Telemetry answered 7/4, 2019 at 17:15 Comment(0)
S
0

You can use a list of object with id as a key, then update using the id reference: https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects

docRef.update({
  object: {
    count: admin.firestore.FieldValue.increment(1),
    `list.${user_id}`: {
      space_id: newData.date_id,
      user: {
        user_id,
        displayName: "john doe"
      }
    }
  }
})
Seaware answered 2/4, 2020 at 20:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.