Badger 29
Badger 29

Reputation: 113

How do I add to an array in Angular Firestore?

Im trying to add ids to my user collection for Access Control in Firestore using Angular Fire 2.

 grantCompanyAccess (user, companyId) {
    try {
      const userAccess: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.uid}`);
      return userAccess.set({companies: [companyId]});
    } catch (error) {
      console.log(error);
    }
  }

  removeCompanyAccess (user, companyId) {
    try {
      const userAccess: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.uid}`);
      const userData = {
        companies:  [{companyId}]
      };
      // return userAccess.collection('companies').doc(companyId).delete();
      return userAccess.collection('companies').doc(companyId).delete();
    } catch (error) {
      console.log(error);
    }
  }

Currently grant method is replacing the id in the array. How do I add to the array if the value does not exist ({merge: true} does not work) and delete from the array using the remove method.

Upvotes: 2

Views: 3901

Answers (3)

ASomN
ASomN

Reputation: 198

There is no need for a cloud function, use arrayUnion:

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

The above from the documentation linked by Pepe: https://firebase.google.com/docs/firestore/manage-data/add-data#web-v8_11

Upvotes: 2

azrahel
azrahel

Reputation: 1213

I think answer marked as accepted is wrong. I know OP asks 'in Angular Firestore' but proposed answer provides OP with solution that will harm him and I believe that's not good.

If you have more then one source that can update the data (ex. few users of app) you will sooner or later end up loosing data. Accepted answer doesn't solve concurrency issue.

Imagine this scenario:

  1. User A fetches the data and array he wants to update looks like this: [1,2,3]

  2. User A now adds one element (4) -> [1,2,3,4] (not posting to server yet)

  3. User B now fetches the same data (array looks like this [1,2,3])

  4. User A now posts to server (new data that is on server and looks like this [1,2,3,4]

  5. User B puhes one element (5) to array that he has locally and it looks like this now [1,2,3,5]. He now pushes to server.

  6. As an effect data on the server gets overwriten and server holds [1,2,3,5]

  7. As an effect (4) value that User A pushed in step 2 is now lost from the array.

Actual solution to what you want to do is to use Firestore Cloud Function within which you can use ArrayUnion method. Then expose that function through either HTTP or callable endpoint and than use if from your app. Do not do it using AngularFirestore as for now it does not provide suficient solution.

Hope it helps, cheers

Upvotes: 0

RobrechtVM
RobrechtVM

Reputation: 936

You should first get the array from firebase and then push your new id into that array. After that you can set companies with the updated array.

Upvotes: 0

Related Questions