Firestore arrayunion provides any callback?

100 views Asked by At

Hi I am building some kind of voting system and I have like to prevent the same user from voting in the same post.

  let db = firebase.firestore();
  var postRef = db.collection("posts").doc(this.pid);
  postRef.update({
    votes: firebase.firestore.FieldValue.increment(1)
  });
  var userRef = db.collection("users").doc(this.userId);
  userRef.update({
    votes: firebase.firestore.FieldValue.arrayUnion(this.pid)
  });
  //run this line if pid is added
  this.votes = this.votes + 1;

I have like to increase the vote only if pid is added to the votes array. I wonder if arrayUnion is able to provide some kind of feedback on this or anyway I can do that.

You can look at this post and you can see that the same person can vote multiple times on the same post.

1

There are 1 answers

0
Francesco Colamonici On BEST ANSWER

Unfortunately, by design increment and arrayUnion don't provide any callback.

In order to implement your requirement, you need a transaction (used by both increment and arrayUnion under the hood):

const postRef = db.collection("posts").doc(this.pid);
const userRef = db.collection("users").doc(this.userId);

db.runTransaction(async (t) => {
    const post = await t.get(postRef);
    const user = await t.get(userRef);

    if (!user.get('votes').includes(this.pid)) {
        t.update(postRef, {votes: post.get('votes') + 1});
        t.update(userRef, {votes: [...user.get('votes'), this.pid]});
    }
});