3

Ich habe andere Beiträge über Probleme mit $ save() gesehen, aber ich konnte es nicht auf meinen Code beziehen. Ich habe einen Profil-Controller mit einer updateProfile() -Methode, die letztendlich versucht, die neuen Daten nach ihrer Änderung in der Datenbank zu speichern.

Ich habe meine Profil-Controller wie folgt definiert:

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

Mein Benutzerservice:

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

Profil Zustand von Haupt App:

.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

Aus irgendeinem Grund bekomme ich einen Fehler, dass profileCtrl.profile. $ Save() ist keine Funktion. Ich weiß, dass das profileCtrl.profile-Objekt legitim ist und ich $ save() entsprechend verwende, aber ich kann einfach nicht herausfinden, was sonst das Problem sein könnte.

Mein Bauchgefühl ist, dass mir etwas Einfaches fehlt, aber ich bin brandneu bei AngularJS und Firebase, also würde mich das nicht wundern.

+1

Sie können '$ save' nur auf einem' firebaseObject' oder auf einem 'FirebaseArray' aufrufen, ist Ihr' profileCtrl.profile' jemand von ihnen. Lesen Sie mehr unter: https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebaseobject-save – Adi

+0

Ich habe etwas Code hinzugefügt, um eine bessere Vorstellung von dem zu geben, was vor sich geht. "Profil" ist eine Abhängigkeit, die Teil einer resolve-Methode ist, die ein firebaseObject über den Benutzercontroller zurückgibt. Ich habe ein Debugging durchgeführt, und soweit ich das beurteilen kann, ist es ein firebaseObject. –

Antwort

1

In der resolve Ihres "Profil" Status geben Sie nichts zurück.

sollten Sie beheben es an:

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

Außerdem sollten Sie da halten nicht den Verweis auf die $firebaseArray aber für jeden Controller erstellen, die es verwenden möchte.

Die Kehrseite ist, dass Sie einige Änderungen vornehmen müssen, werden, aber die Aufwärtsseite ist ein berechenbarer, wartbaren Code:

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

auf das neue AngularFire docs Siehe auch: API reference

+0

Lassen Sie uns zunächst Entschlossenheit Methode sprechen: Überprüfen Sie diese heraus: onAuthStateChange: https://firebase.google.com/docs/reference/js/firebase.auth.Auth#onAuthStateChanged $ requireAuth: https: // www .firebase.com/docs/web/libraries/angular/api.html # angularfire-users-and-authentication-requiryauth onAuthStateChange gibt kein Versprechen wie das abgeschriebene $ requireAuth() zurück, das in verwendet wurde diese Situation, so. dann() wird nicht funktionieren. Die Abhängigkeit 'Profil' wird nur zurückgegeben, wenn ein Benutzer gültig ist. 'auth' muss nichts zurückgeben, da ich firebase.auth(). currentUser verwenden kann, um den Benutzer abzurufen. –

+0

P.S. Diese App stammt von einem veralteten AngularFire-Tutorial, das ich zu aktualisieren versuche. Vielleicht ergibt das deshalb einen Sinn. Außerdem wurde der Code mit einem Fehlerprotokoll aktualisiert, um Ihnen eine bessere Vorstellung davon zu geben, was zurückgegeben wird. –

+0

Sie verwenden das Firebase 3 SDK, haben jedoch eine Verbindung zu AngularFire 1 hergestellt, die nur Firebase 2 SDK unterstützt. Von der Verknüpfung, die Sie hinzufügen, gibt der 'onAuthStateChanged' eine Funktion zurück, aber es ist für das Abmelden, deshalb hat es nicht' $ save' – idan