angularfire2 best way to increment a value?

可紊 提交于 2019-12-18 04:17:13

问题


I searched in many forums, questions, in doc but can't find the correct solution.

Problem

What is the best way to increment a value using angularfire2 ?
I saw we could use [transaction()][] but it's not for angularfire2 actually. Or with snapshot ?

user.service.ts

incrementLike(userToIncrementLike){
    this.af.database.object('users/' + userToIncrementLike.uid).subscribe((userObject) => {
      var newUser = {
        likes: userObject.likes + 1
        };

     });
     this.af.database.object('users/' + userToIncrementLike.uid).update(newUser);

  }

I tried also in this way :

incrementLike(userToIncrementLike){

    let obs = this.af.database.object('users/' + userToIncrementLike.uid);
    obs.subscribe((snapshot) => {
      let newValue = (snapshot.$value) ? (snapshot.$value + 1) : 1;
      obs.set(newValue);
    });
  }

Thank you very much for your help and tips :) Luis.


回答1:


It isn't necessary to define an object or to use the update() method. The object already exists in the database, so you can just work on it there. This is actually the purpose of transaction()--to work on the data at the data location and therefore prevent conflicts; e.g., two users updating the same value at the same time.

You can also use the template literal in your path if you like. :) (Note the backticks instead of single quotes.)

incrementLike(userToIncrementLike){
    this.af.database.object(`users/${userToIncrementLike.uid}/likes`).query
    .ref.transaction(likes => {
        if (likes === null) {
            return likes = 1;
        } else {
            return likes + 1;
        }
    })
}

Update: September, 2019. Use query instead of $ref.




回答2:


"angularfire2 V5" Solution:

incrementLike(userToIncrementLike){
this.af.database.object(`users/${userToIncrementLike.uid}/likes`)
  .query.ref.transaction((likes => {
    if (likes === null) {
        return likes = 1;
    } else {
        return likes + 1;
    }
})};



回答3:


Firestore now has increment() which correctly increments a field even if multiple users are competing to edit at the same time

Incrementing Values Atomically with Cloud Firestore

To use this in angularfire2

import { firestore } from 'firebase/app';

incrementLike(userToIncrementLike) {
    const increment = firestore.FieldValue.increment(1);
    const userLike = this.af.doc(`users/${userToIncrementLike.uid}`);
    userLike.update({ likes: increment });
}

I used firestore directly since I couldn't find FieldValue in angularfire2.




回答4:


@angular/fire (Angular version 7)

https://firebase.google.com/docs/firestore/manage-data/transactions https://firebase.google.com/docs/firestore/query-data/get-data

incrementLike(userToIncrementLike) {

  //VARIABLE FOR MANAGING THE SCOPE
  var that = this;
  this.afs.firestore.collection("users").where("id", "==", userToIncrementLike.uid)
  .get()
  .then(function(querySnapshot) {

     querySnapshot.forEach(function(doc) {
        // doc.data() is never undefined for query doc snapshots
        console.log(doc.id, " => ", doc.data());

        return that.afs.firestore.runTransaction(function(transaction) {
           // This code may get re-run multiple times if there are conflicts.
           return transaction.get(doc.ref).then(function(doc) {
              if (!doc.exists) {
                 throw "Document does not exist!";
              }

              //THIS IS WHERE TO DO THE INCREMENT
              var new_score = doc.data().score + 1;
              transaction.update(doc.ref, { score: new_score });
           });
        }).then(function() {
           console.log("Transaction successfully committed!");
        }).catch(function(error) {
           console.log("Transaction failed: ", error);
        });

     });
  })
  .catch(function(error) {
     console.log("Error getting documents: ", error);
  });

}



回答5:


I use it on Firestore. This same code use to practically work on realtime DB.

"@angular/fire": "^5.1.2"

const login = this.afs.doc(`/users/${uid}`);
    login.valueChanges()
        .pipe(take(1))
        .subscribe((user: User) => {
            login.update({ login: user.login as number + 1 });
        });


来源:https://stackoverflow.com/questions/42596866/angularfire2-best-way-to-increment-a-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!