0

I'm trying to get the profile image of a user stored in Firebase at /user/[uid]/info/photoURL

I am doing this using Angular functions.

My Code

HTML:

<img ng-src="{{getImg(user.uid)}}" alt="">

Javascript:

$scope.getImg = function(uid) {
  // return uid;
    promise = firebase.database().ref("/users/" + uid + "/info/").once("value");
    promise.then(function(snapshot) {
      return snapshot.val().photoURL;
    }, function() {
      return "Error :(";
    });
};

I am getting: TypeError: snapshot.val(...) is null

I have also tried:

firebase.database().ref("/users/" + uid + "/info/").once("value").then(function(snapshot) {
     return snapshot.val().photoURL;
 });

But that does not return any data.

Edit:

Here is the structure of what I am trying to load:

  "[user uid]" : {
    "info" : {
      "name" : "Jett Jackson",
      "photoURL" : "[URL to photo]"
    }
  }

Edit: Using this in ng-repeat and for a single user.

Edit: here is the surounding code:

route.controller("dashController", ["$scope", "$http", "$routeParams", "$firebaseArray", "$firebaseObject", "$sce", function($scope, $http, $routeParams, $firebaseArray, $firebaseObject, $sce) {
    var postsRef = firebase.database().ref().child("posts"),
    query = ($firebaseArray(postsRef), postsRef.orderByChild("timestamp").limitToLast(5));
    $scope.posts = $firebaseArray(query);

    firebase.auth().onAuthStateChanged(function(user) {
        user ? $scope.user = user : $scope.user.displayName = "Signed Out";
    });
    $scope.getImg = function(uid) {
  // return uid;
    promise = firebase.database().ref("/users/" + uid + "/info/").once("value");
      promise.then(function(snapshot) {
        return snapshot.val().photoURL;
      }, function() {
        return "Error :(";
      });
   };

}]);

HTML:

In the posts:

  <div ng-repeat="post in posts | reverse" class="item">
    <a href="/#/post/{{post.$id}}"><div class="img">
      <img src="{{post.thumbnail}}" alt="">
    </div></a>
      <div class="column center-vert">
        <h1>{{post.title}}</h1>
        <p>{{post.preview}}</p>
      <div class="icons row">
        <i class="icon-heart"></i>{{post.starCount}}<div class="pad"></div><i class="icon-user"></i>
        <div class="timestamp">12 hours ago</div>
      </div>
    </div>
      <div class="author">
      <img src="{{getImg(post.uid)}}" alt="">
      <p>{{post.author}}</p>
    </div>
  </div>

In the user:

<div class="userImageContainer">
  <img ng-src="{{getImg(user.uid)}}" alt="">
</div>
J_tt
  • 13
  • 1
  • 7
  • are you able to share a sample document/row ? Just want to checkout the document model. – Searching Nov 02 '16 at 23:44
  • can you `console.log(uid)` and check if the `uid` is being passed correctly. Nothing seems to be wrong in the query for the structure. – Searching Nov 03 '16 at 20:17
  • I looked closesly, and it appears the function is running before the user's uid is loaded. – J_tt Nov 03 '16 at 22:45
  • It is quite hard to comment or say THIS is the issue, I can only guess. Are you are trying to load these details say in `ng-repeat` with `user.photoURL` and `user.name` or is it only for a single `user` in a page ? Update the question instead of commenting here, will help others too. `user` is probably still `null` – Searching Nov 03 '16 at 23:16
  • I'm loading this in both an `ng-repeat` and a single user – J_tt Nov 03 '16 at 23:18
  • Update both html and the controller in the question for this page you get the error so we know exactly how things are setup. Don't need firebase config you can omit that. So far what you provided is looking good the error might be elsewhere..probably the way it's loading.. – Searching Nov 03 '16 at 23:29
  • Edited main post. – J_tt Nov 03 '16 at 23:39
  • Is the html relevant for the controller you provided ? It seems you provided it for the `post` and not the `user` .. – Searching Nov 03 '16 at 23:47
  • At which line of your code you TypeError: snapshot.val(...) is null error? – Aniruddha Das Nov 04 '16 at 00:33

3 Answers3

0

This assumes post.uid == user.uid

For the user issue it is loaded after the onAuthStateChanged is fired. Until then $scope.user is empty/unknown.

One option is after the user is downloaded inside onAuthStateChanged $broadcast the event and use $on like this.

$scope.UserProfilePhoto = ""; // declare empty photo url

firebase.auth().onAuthStateChanged(function (user) {
    user ? $scope.user = user : $scope.user.displayName = "Signed Out";
    $scope.$broadcast('user-logged-in'); //boardcast that the user is now available
});

//listen for user logged in
$scope.$on('user-logged-in', function (event, args) {
    //now you should have the user id here. Call your getImg
    $scope.UserProfilePhoto = $scope.getImg($scope.user.uid);
});

$scope.getImg = function (uid) {
    // return uid;
    promise = firebase.database().ref("/users/" + uid + "/info/").once("value");
    promise.then(function (snapshot) {
        return snapshot.val().photoURL;
    }, function () {
        return "Error :(";
    });
};

html

<img ng-src="{{UserProfilePhoto}}" alt="">

Let us know how it goes. Some reading https://stackoverflow.com/a/14502755/1339516

Community
  • 1
  • 1
Searching
  • 2,269
  • 1
  • 17
  • 28
  • post.uid and user.uid are the same, post.uid refers to the user id of the author, and user.uid refers to the users id, I will try your suggestion and see how it goes! – J_tt Nov 04 '16 at 08:20
  • So it's getting called fine, but I can't get `$scope.userPhotoUrl` to actually end up being the photourl, it always results in undefined, I can successfully console log the photo url when it is called, but the $scope variable will remain undefined. – J_tt Nov 04 '16 at 09:00
  • I've scrapped the getImg function and decided to instead get the user/Info object from the user loaded event, works perfectly, just need to get something for the ng-repeat... – J_tt Nov 04 '16 at 09:43
  • I removed the getImg function and improved my code considerably, see my answer. Thank you for your help! – J_tt Nov 04 '16 at 10:46
0

First check the the facebase API which provides any val() oor not as in the callback function root return value (snapshot) is undefined.

// might be snapshot does not have a val()
snapshot.val()
Aniruddha Das
  • 20,520
  • 23
  • 96
  • 132
0

Using angular functions in a ng-repeat loop turned out to be a bad idea. I fixed my issue by changing my code to:

Posts:

var postsRef = firebase.database().ref().child("posts");
    query = ($firebaseArray(postsRef), postsRef.orderByChild("timestamp").limitToLast(5));
    $scope.posts = $firebaseArray(query);
    $scope.posts.$loaded(function() {
      var length = $scope.posts.length;
      for (var i = 0; i < length; i++) {
          var uid = $scope.posts[i].uid;
          if ($scope.postUser[uid]!==undefined){
          } else {
            ref[uid] = firebase.database().ref().child("/users/" + uid + "/info/");
            $scope.postUser[uid] = $firebaseObject(ref[uid]);
          }
      }

User:

$scope.$on('user-logged-in', function (event, args) {
        var ref = firebase.database().ref().child("/users/" + $scope.uid + "/info/");
        $scope.user = $firebaseObject(ref);
    });

Which arguably it should have been before.

Thanks @Searching for your help <3

J_tt
  • 13
  • 1
  • 7