AngularFire $ save()不是函数

时间:2016-08-02 23:25:49

标签: javascript angularjs firebase firebase-realtime-database angularfire

我已经看过有关$ save()问题的其他帖子,但我无法将其与我的代码联系起来。我有一个带有updateProfile()方法的配置文件控制器,它最终会在更改后尝试将新数据保存到数据库中。

我已将我的配置文件控制器定义如下:

angular.module('angularfireSlackApp')
.controller('ProfileCtrl', function($state, md5, profile) {
 var profileCtrl = this;
 var currentUser = firebase.auth().currentUser;
 profileCtrl.profile = profile;

// Retrieves the user's email from input field, hashes it, and saves the data to the database
profileCtrl.updateProfile = function() {
console.log(profileCtrl.profile); // Profile object exists and is populated as expected
profileCtrl.profile.emailHash = md5.createHash(currentUser.email);
profileCtrl.profile.$save();
}
});

我的用户服务:

angular.module('angularfireSlackApp')
// Provides a means of retrieving User data or list of all Users
.factory('Users', function($firebaseArray, $firebaseObject) {
// Provides a means of retrieving User data or list of all Users
 // Create a reference to users that can be used to retrieve an array of users
 var usersRef = firebase.database().ref("users");
 users = $firebaseArray(usersRef);


 var Users = {
   // Returns a firebase object of a specific user's profile
   getProfile: function(uid) {
     return $firebaseObject(usersRef.child(uid));
   },
   // Returns the display name of a specific user
   getDisplayName: function(uid) {
     return users.$getRecord(uid).displayName;
   },
   // Returns the Gravatar url that corresponds to the user
   getGravatar: function(uid) {
     return 'www.gravatar.com/avatar/' + users.$getRecord(uid).emailHash;
   },
   // Returns a firebase array of users
   all: users
 };

 return Users;
});

主应用程序的配置文件状态:

.state('profile', {
      url: '/profile',
      controller: 'ProfileCtrl as profileCtrl',
      templateUrl: 'users/profile.html',
      resolve: {
        auth: function($state) {
          firebase.auth().onAuthStateChanged(function(user) {
            if (user == null) {
              $state.go('home');
              console.log("In auth but user NOT valid");
            } else {
              console.log("In auth and user valid");
            }
          });
        },
        profile: function(Users) {
          firebase.auth().onAuthStateChanged(function(user) {
            if (user != null) {
              console.log("In profile and user valid");
              return Users.getProfile(user.uid).$loaded();
            } else {
              console.log("In profile but user NOT valid");
            }
          });
        }
      }
  });

的console.log:

debug

出于某种原因,我收到了profileCtrl.profile。$ save()不是函数的错误。我知道profileCtrl.profile对象是合法的,并且我正确地使用$ save(),但我无法弄清楚还有什么可能是问题。

我的直觉是,我错过了一些简单的东西,但我是AngularJS和Firebase的新手,所以我不会感到惊讶。

1 个答案:

答案 0 :(得分:1)

在您的“个人资料”状态的resolve中,您没有返回任何内容。

您应该将其修复为:

auth: function($state, $firebaseAuth) {
  return $firebaseAuth().$onAuthStateChanged().then(function(user) {
    if (!user) {
      $state.go('home');
      console.log("In auth but user NOT valid");
    } else {
      console.log("In auth and user valid");
    }
  }); // classic situation to use $requiresAuth() 
},
profile: function(Users, $firebaseAuth) {
  return $firebaseAuth().$requireSignIn();
}

此外,您的服务不应该保留对$firebaseArray的引用,而是为每个想要使用它的控制器创建它。

缺点是你必须做出一些改变,但是上行是一个更可预测,可维护的代码:

    var Users = {
    // Returns a firebase object of a specific user's profile
    getProfile: function(uid) {
        return $firebaseObject(usersRef.child(uid));
    },
    // Returns the display name of a specific user
    getDisplayName: function(uid) {
        // This is actually an issue to get the name synchronously, but I see no reason why not using the Firebase SDK and fetch a-sync
        //return users.$getRecord(uid).displayName;
        return usersRef.child(uid)
            .child('displayName')
            .once('value')
            .then(function (snap) {
                return snap.val();
            });
    },
    // Returns the Gravatar url that corresponds to the user
    getGravatar: function(uid) {
        // Again fetch a-synchronously
        //return 'www.gravatar.com/avatar/' + users.$getRecord(uid).emailHash;
        return usersRef.child(uid)
            .child('emailHash')
            .once('value')
            .then(function (snap) {
                return 'www.gravatar.com/avatar/' + snap.val();
            });
    },
    // Returns a firebase array of users
    all: function () {
        return $firebaseArray(usersRef);
    }
};

另请参阅新的AngularFire文档:API reference