angularfire2 增加价值的最佳方式?
angularfire2 best way to increment a value?
我在许多论坛、问题和 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);
});
}
非常感谢您的帮助和提示:)
路易斯.
不必定义对象或使用 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
。
"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;
}
})};
@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);
});
}
我在 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 });
});
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 });
}
在angularfire2中找不到FieldValue
,直接用firestore
我在许多论坛、问题和 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);
});
}
非常感谢您的帮助和提示:) 路易斯.
不必定义对象或使用 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
。
"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;
}
})};
@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);
});
}
我在 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 });
});
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 });
}
在angularfire2中找不到FieldValue
,直接用firestore