2

I want to remove multiple elements from my Firestore array:

var eliminatedThisRound = []

for (const player in players){
    if (players[player].eliminated === false && players[player].answer !== answer) {
        eliminatedThisRound.push(players[player].uid);
    }
}
var update = {
    roundFinished: true,
    nextRound: date.valueOf() + 12000,seconds
    players: updatedPlayers,
    remainingPlayers: admin.firestore.FieldValue.arrayRemove(eliminatedThisRound)
}
await t.update(gameRef, update);

The above returns this error:

transaction failure: Error: Element at index 0 is not a valid array element. Nested arrays are not supported. 

So it would be fine if I knew the values, as I could do something like this:

remainingPlayers: admin.firestore.FieldValue.arrayRemove("player1", "player2")

However I haven't found a way to make the parameter of arrayRemove() dynamic.

Any idea?

3
  • As far as I can see you should be able to pass in multiple values for arrayRemove: firebase.google.com/docs/reference/js/… and firebase.google.com/docs/reference/js/…. What happens when you pass multiple values? Is there an error message? Commented Jan 3, 2021 at 7:21
  • Yes that's right - but my values are dynamic. I tried to pass in an array which had multiple values in it (eliminatedThisRound in my code above) - however it returned this error: Element at index 0 is not a valid array element. Nested arrays are not supported. Commented Jan 3, 2021 at 8:05
  • Ah, that error message makes sense (please include that right away in the future). The spread operator in Renaud's answer should make that error disappear. Commented Jan 3, 2021 at 16:31

2 Answers 2

7

You need to use the Spread operator, as follows, in order to pass all elements of eliminatedThisRound as arguments to the arrayRemove() method.

var eliminatedThisRound = []

for (const player in players){
    if (players[player].eliminated === false && players[player].answer !== answer) {
        eliminatedThisRound.push(players[player].uid);
    }
}
var update = {

    // ...

    admin.firestore.FieldValue.arrayRemove(...eliminatedThisRound)
}

await t.update(gameRef, update);

Note that you should have at least one element in the Array, otherwise you will call arrayRemove() with 0 argument while it requires at least 1 argument. So you may check the array length before assigning the remainingPlayers property to the update Object.

Sign up to request clarification or add additional context in comments.

Comments

1

You can pass a single value or an array of values from variables like this to arrayRemove():

var removingPlayersId = ['player1', 'player2'];
  admin
    .firestore()
    .doc('game/someID')
    .set(
      {
        remainingPlayers: admin.firestore.FieldValue.arrayRemove(
          removingPlayersId
        ),
      },
      { merge: true }
    );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.