保存新 属性 覆盖 firebase 对象

saving new property overwrites firebase object

我正在使用 firebase 和 angular 进行测验。在测验结束时,我想使用以下代码将新的 属性 保存到用户对象:

function saveTopscore() {
    var ref = new Firebase(CONSTANTS.FIREBASE_URL + 'users/' + User.user.$id + '/');
    var userObject = $firebaseObject(ref);
    userObject.topscore = User.totalCorrect;
    userObject.$save().then(function(ref) {
        console.log("worked");
    }, function(error) {
        console.log(error);
    });
}

它有效,但它也会覆盖用户对象的所有属性。所以这个对象曾经像名字、用户名、电子邮件、密码等一样保存,但是当我推送最高分时,它变成了对象的唯一 属性。为什么?

为什么在这里使用 $firebaseObject?这仅在您将其三向绑定到 Angular 视图时才有用。如果您使用的是常规 JavaScript 代码,请坚持使用 Firebase 的常规 JavaScript SDK。

在这种情况下,只需执行:

ref.update({ topscore: User.totalCorrect });

如@Frank 所说,使用 JavaScript SDK。

我想澄清一下原始上下文(使用 $firebaseObject),以防将来其他人提到这个问题。

  • 出现最初的症状是因为您正在设置对象的单个参数并在对象(及其已经存在的子对象)完全下载之前保存它。
  • 因此,当您调用 .$save() 时,userObject 将(很可能)仅设置其 topscore 参数,调用 .$save() 将有效地删除Firebase ref.
  • 中所有其他已存在的子项

您可以避免这种情况,使用 .$loaded() 等到对象完全下载后再修改 and/or 更新它...

编辑: 然而,正如 Intro to AngularFire 指南所述,

The $loaded() method should be used with care as it's only called once after initial load. Using it for anything but debugging is usually a poor practice.

如果您忽略此警告并仍然使用 $loaded(),该实现可能如下所示:

注意 - 反模式:这不是推荐的做法。

var ref = new Firebase(fbUrl + '/users/' + User.user.$id + '/');
var userObject = $firebaseObject(ref);
// wait until userObject has been downloaded, then modify & save it.
userObject.$loaded().then(function(){
  userObject.topscore = User.totalCorrect;
  userObject.$save().then(function(ref) {
      console.log("Saved");
  }, function(error) {
      console.log(error);
  });
});

正如 Frank 在此回答的评论中所说,

"If you're using $loaded() straight after $firebaseObject (or $firebaseArray), you're probably doing something wrong."