【问题标题】:angularfire2 best way to increment a value?angularfire2 增加值的最佳方法?
【发布时间】:2017-03-04 13:59:46
【问题描述】:

我在doc 中搜索了许多论坛、问题,但找不到正确的解决方案。

问题

使用 angularfire2 增加值的最佳方法是什么?
我看到我们可以使用 [transaction()][] 但它实际上不适用于 angularfire2。 还是用快照?

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

  }

我也试过这种方式:

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

非常感谢您的帮助和提示 :) 路易斯。

【问题讨论】:

  • 您所描述的内容并不完全合理。喜欢的数量变为完全 1340 或类似的东西?你的console.log 会触发 1340 次吗?
  • 是的,所以我检查并修改了我的问题:它恰好增加了 1321 次,所以 1321...2642.. 在控制台中它也被调用了 1321 次。我也更新了可能的解决方案。 :)
  • 好吧,我解决了我的问题 :D 还是谢谢你!
  • @luiswill 请提供您的解决方案作为单独的答案。 Stack Overflow 鼓励自我回答,并提供了一种建立声誉的好方法。

标签: angular firebase ionic2 angular2-services angularfire2


【解决方案1】:

Firestore 现在有 increment(),即使多个用户同时竞争编辑,它也会正确递增字段

Incrementing Values Atomically with Cloud Firestore

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

我直接使用了firestore,因为我在angularfire2中找不到FieldValue

【讨论】:

  • 这应该是公认的答案,因为它是最新的
【解决方案2】:

不必定义对象或使用update() 方法。该对象已存在于数据库中,因此您可以在那里处理它。这实际上是transaction()--to work on the data at the data location 的目的,因此可以防止冲突;例如,两个用户同时更新相同的值。

如果您愿意,也可以在路径中使用模板文字。 :)(注意反引号而不是单引号。)

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

更新:2019 年 9 月。使用 query 代替 $ref

【讨论】:

  • 是的,您的代码完美运行!一开始我以为你不能使用事务,因为它是 Firebase SDK 中的一个函数,而不是 angularfire2 ......但是使用 .$ref 你可以做到:)谢谢!
  • 是哪个版本的?
【解决方案3】:

“angularfire2 V5”解决方案:

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

【讨论】:

    【解决方案4】:

    @angular/fire(Angular 版本 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】:

      我在 Firestore 上使用它。这段代码实际上用于实时数据库。

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

      【讨论】:

        猜你喜欢
        • 2020-09-05
        • 1970-01-01
        • 2011-02-27
        • 1970-01-01
        • 1970-01-01
        • 2020-10-07
        • 2020-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多