0
votes

Ok, so I'm working with AngularJS and Firebase and trying to create a simple exchange between two users. Right now my data structure is set up under "users/uId/" and then their email, date they joined, and gold.

Under gold (users/uId/gold) I have "sent" which captures the amount, time and to whom (email). This is the code snippet below. It also updates their total gold.

Now I'm stuck updating the person they're sending the gold to. I capture the email address, but everything under scope relates to the current logged in user. How would I update the new users users/uId/gold/received with the amount, time and email who it was from, along with updating their total gold?

I feel like I might be going about this the wrong way, any help would be appreciated, thanks!

ledger.controller('TransferController', function (
$scope, $firebase, $routeParams, $location, $rootScope, FIREBASE_URL) {

    $scope.whichuser = $routeParams.uId;
    $scope.goldsends = goldsendList;

    var ref = new Firebase(FIREBASE_URL + '/users/' + $scope.whichuser + '/gold/' + '/sent/');
    var hopperRef = new Firebase(FIREBASE_URL + '/users/' + $scope.whichuser + '/gold/');
    var usersRef = ref.child("users");
    var goldsendList = $firebase(ref).$asArray();


    $scope.sendGold = function () {
        var sendgoldObj = $firebase(ref); //this var has to match the sendgoldObj.$push var down below, and that's it

        var myData = {
            amount: $scope.user.amount,
            email: $scope.user.email,
            date: Firebase.ServerValue.TIMESTAMP
        };

        sendgoldObj.$push(myData).then(function () {
            //   $location.path('/myledger/');  //page redirect
        }); //data sent to firebase.

        if ($scope.currentUser.gold.total - Math.abs($scope.user.amount) > 0) { //

            var hopperRefff = hopperRef.child("gold");
            hopperRef.update({
                "total": $scope.currentUser.gold.total - $scope.user.amount
            }); //update total gold

            var receive = new Firebase(FIREBASE_URL);
            ref.child('users').orderByChild('email').equalTo(emailAddress).once('value', function (snap) {
                console.log(snap.name() + (snap.val() === null ? ' DOES NOT' : ' does') + ' exist');
            }); //trying to find user to send gold to

        } //if user has enough gold statement
        else {
            return {
                scope: {
                    errormessage: 'You don\'t have enough money',
                }
            };
            console.log("not enough money!");
        } //else note enough gold statement

    } //sendgold
}); //TransferController
2
You have the right approach with ref.child('users').orderByChild('email').equalTo(emailAddress). So what is the problem with that code fragment? - Frank van Puffelen
That code works for telling me if the email exists in the database, but then how do I push data to that user? - Alteredorange

2 Answers

0
votes

Setting a value to the user is just a variation of checking if that user exists. Once you have a snapshot, you can get back to a ref by calling ref

ref.child('users').orderByChild('email').equalTo(emailAddress).once('value', function (snap) {        
    snap.ref().update({ "total": snap.val().total + amount });
});

Not that this is just a sample, so you'll probably have to update it for your actual data structure.

Update

The above will get you the value of the users node.

You either need to capture the once('child_added' or forEach over the on('value'. I'll give an example of both.

Listening to child_added:

ref.child('users').orderByChild('email').equalTo(emailAddress).once('child_added', function (snap) {        
    snap.ref().update({ "total": snap.val().total + amount });

});

An example of looping over the value:

ref.child('users').orderByChild('email').equalTo(emailAddress).once('value', function (snap) {        
    snap.forEach(function(childsnap) {
        childsnap.ref().update({ "total": snap.val().total + amount });

});

Here's a jsbin with both samples: http://jsbin.com/fenavu/1/edit?js,console. Note that the code here writes out the ref.toString(), which gives you the full URL of the node (since every piece of data in Firebase has its own unique URL). That can be a handy way to figure out what URL your node maps to.

1
votes

You could store the users by email where the @ is replaced by _ and a . is replaced with -

So you have a JSON structure like this in Firebase

users: {
   "bob_hoskins-com": { 
      email: "[email protected]",
      date: "09-09-1999",
      gold: {
          ...
      }
   }
}

However, I don't think this is a great approach for this problem.

I would create a node service that is observing a requests Firebase location on each user for added children. The node service will then do the calculations and write the data to the correct paths, then can delete the request once processed.

So you would have rules on your Firebase like this

{
  "rules": {
    "$userId": {
      "requests": {
        ".read": "auth != null && $userId == auth.id",          
        ".write": "auth != null && $userId == auth.id"          
      },
      "responses": {
        ".read": "auth != null && $userId == auth.id",
        ".write": "auth != null && $userId == auth.id"          
      }
   }
}

Here is some request code

var Firebase = require('firebase');

function s4() {
  return Math.floor((1 + Math.random()) * 0x10000)
             .toString(16)
             .substring(1);
}

function guid() {
  return s4() + s4() + s4() + s4();
}

var _ref = new Firebase('https://YOUR_FIREBASE.firebaseio.com/');

//Log me in
var guid = guid();
var FirebaseTokenGenerator = require("firebase-token-generator");
var tokenGenerator = new FirebaseTokenGenerator("YOUR_TOKEN");
var TOKEN = tokenGenerator.createToken({uid: guid, user: "node server"},{admin: true});

_ref.authWithCustomToken(TOKEN, function (error) {
  if(error) {
    console.log("Login Failed!", error);
  } else {
    console.log("Login Succeeded!", guid);
  }
});

_ref.on('child_added', function (user) {
    var requests = user.ref().child('requests');
    requests.on('child_added', function(req) {
        handleRequest(req);
    });
});

var handleRequest = function (request) {
   // Process the request
   // Write stuff back to Firebase

   // Delete the request
   request.ref().remove();
};