Mehrnoosh
Mehrnoosh

Reputation: 899

Update collection with an array in firebase

I need to update a collection in values like this :

{
  "email" : "[email protected]",
  "fullName" : "Mehr",
  "locations" : ["sss","dsds","adsdsd"]
 }

Locations needs to be an array. in firebase how can I do that ... and also it should check duplicated.

I did like this :

 const locations=[]
 locations.push(id)

firebase.database().ref(`/users/ + ${userId}`).push({ locations })

Upvotes: 0

Views: 1249

Answers (3)

Frank van Puffelen
Frank van Puffelen

Reputation: 599001

Since you need to check for duplicates, you'll need to first read the value of the array, and then update it. In the Firebase Realtime Database that combination can is done through a transaction. You can run the transaction on the locations node itself here:

var locationsRef = firebase.database().ref(`/users/${userId}/locations`);
var newLocation = "xyz";

locationsRef.transaction(function(locations) {
  if (locations) {
    if (locations.indexOf(newLocation) === -1) {
      locations.push(newLocation);
    }
  }
  return locations;
});

As you can see, this loads the locations, ensures the new location is present once, and then writes it back to the database.


Note that Firebase recommends using arrays for set-like data structures such as this. Consider using the more direct mapping of a mathematical set to JavaScript:

"locations" : {
  "sss": true,
  "dsds": true,
  "adsdsd": true
}

One advantage of this structure is that adding a new value is an idempotent operation. Say that we have a location "sss". We add that to the location with:

locations["sss"] = true;

Now there are two options:

  1. "sss" was not yet in the node, in which case this operation adds it.
  2. "sss" was already in the node, in which case this operation does nothing.

For more on this, see best practices for arrays in Firebase.

Upvotes: 2

MuruGan
MuruGan

Reputation: 1420

You can use update rather than push method. It would much easier for you. Try it like below

var locationsObj={};
if(locations.length > 0) {
    for(i=0; i < locations.length; i++) {
       var key= firebase.database().ref(`/users/ + ${userId}`).child('locations').push().key;
       locationsObj[`/users/ + ${userId}` +'/locations/' + key] =locations[i];
    }
    firebase.database().ref().update(locationsObj).then(function(){// which return the promise.
        console.log("successfully updated");
    })  
}

Note : update method is used to update multiple paths at a same time. which will be helpful in this case, but if you use push in the loop then you have to wait for the all the push to return the promises. In the update method it will take care of the all promises and returns at once. Either you get success or error.

Upvotes: 0

Martin Zeitler
Martin Zeitler

Reputation: 76679

you can simply push the items in a loop:

if(locations.length > 0) {
    var ref = firebase.database().ref(`/users/ + ${userId}`).child('locations');
    for(i=0; i < locations.length; i++) {
        ref.push(locations[i]);
    }
}

this also creates unique keys for the items, instead of a numerical index (which tends to change).

Upvotes: 0

Related Questions