Firestore Add value to array field
Asked Answered
S

4

63

Im trying to use Firebase cloud functions to add the id of a chatroom to the users document in an array field. I cant seem to figure out the way to write to an array field type. here is my cloud function

  exports.updateMessages = functions.firestore.document('messages/{messageId}/conversation/{msgkey}').onCreate( (event) => {
    console.log('function started');
    const messagePayload = event.data.data();
    const userA = messagePayload.userA;
    const userB = messagePayload.userB;   

        return admin.firestore().doc(`users/${userA}/chats`).add({ event.params.messageId }).then( () => {

        });

  });

here is the way my database looks

enter image description here

any tips greatly appreciated, Im new to firestore.

Simon answered 12/1, 2018 at 18:19 Comment(1)
Possible duplicate of Append to array FirebaseWeaks
V
136

From the docs, they added a new operation to append or remove elements from arrays. Read more here: https://firebase.google.com/docs/firestore/manage-data/add-data#update_elements_in_an_array

Example:

var admin = require('firebase-admin');
// ...
var washingtonRef = db.collection('cities').doc('DC');

// Atomically add a new region to the "regions" array field.
var arrUnion = washingtonRef.update({
  regions: admin.firestore.FieldValue.arrayUnion('greater_virginia')
});
// Atomically remove a region from the "regions" array field.
var arrRm = washingtonRef.update({
  regions: admin.firestore.FieldValue.arrayRemove('east_coast')
});
Variolite answered 28/9, 2018 at 13:33 Comment(5)
Be careful with details about FieldValue methods.Akanke
arrayUnion will only add the element if it doesn't exist already. Is there a way to add items irrespective of duplicates?Handcar
How to perform the above operations using a transaction?Kreisler
requires update permissions on that pathOceanography
@Handcar what if array contains multiple fieldsLeavy
K
11

Firestore currently does not allow you to update the individual fields of an array. You can, however, replace the entire contents of an array as such:

admin.firestore().doc(`users/${userA}/chats`).update('array', [...]);

Note that this might override some writes from another client. You can use transactions to lock on the document before you perform the update.

admin.firestore().runTransaction(transaction => {
  return transaction.get(docRef).then(snapshot => {
    const largerArray = snapshot.get('array');
    largerArray.push('newfield');
    transaction.update(docRef, 'array', largerArray);
  });
});
Kailyard answered 12/1, 2018 at 22:45 Comment(2)
Note that const largerArray will be converted to a number related to the array.length after the "push" operation. The proper way to do this is create a reference of the array then push, and then use that reference to update the transaction: const largerArray = snapshot.get('array'); largerArray.push('newField')Trinh
This answer is no longer correct. This feature exists. Firebase documentation: firebase.google.com/docs/firestore/manage-data/…Exo
M
11

This is 2021 and after many updates of firebase firestore, the new method to add data in array without removing another data is

      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")
     });

      // Atomically remove a region from the "regions" array field.
    washingtonRef.update({
        regions: firebase.firestore.FieldValue.arrayRemove("east_coast")
      });
Mangrove answered 24/7, 2021 at 10:27 Comment(0)
L
0

With firebase 9.x:

import { getFirestore, FieldValue } from 'firebase-admin/firestore';
import { initializeApp } from 'firebase-admin/app';
import admin from "firebase-admin";

const firebaseAdminApp = initializeApp ({
   credential: admin.credential.cert(serviceAccountCreds) 
});

const db = getFirestore(firebaseAdminApp);

let collectionName = 'cities';
let docID = 'DC'

let docRef = await db.collection(collectionName).doc(docID);
await docRef.update({regions: FieldValue.arrayUnion('Northern Virginia')});
Luo answered 15/7, 2023 at 9:26 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.