使用 AngularJS 和 Firebase 与用户传输项目

Posted

技术标签:

【中文标题】使用 AngularJS 和 Firebase 与用户传输项目【英文标题】:Transfer Items to and from users Using AngularJS and Firebase 【发布时间】:2015-01-21 07:46:26 【问题描述】:

好的,所以我正在使用 AngularJS 和 Firebase 并尝试在两个用户之间创建一个简单的交换。现在我的数据结构设置在“users/uId/”下,然后是他们的电子邮件、他们加入的日期和黄金。

在黄金 (users/uId/gold) 下,我已“发送”,其中包含金额、时间和收件人(电子邮件)。这是下面的代码sn-p。它还更新了他们的总金币。

现在我无法更新他们将黄金发送给的人。我捕获了电子邮件地址,但范围内的所有内容都与当前登录的用户有关。我将如何更新新用户 users/uId/gold/received 的数量、时间和来自谁的电子邮件,以及更新他们的总金币?

我觉得我可能会以错误的方式解决这个问题,任何帮助将不胜感激,谢谢!

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

【问题讨论】:

ref.child('users').orderByChild('email').equalTo(emailAddress) 的方法是正确的。那么这段代码有什么问题呢? 该代码用于告诉我电子邮件是否存在于数据库中,但是我如何将数据推送给该用户? 【参考方案1】:

为用户设置一个值只是检查该用户是否存在的一种变体。获得快照后,您可以通过调用 ref 来返回 ref

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

这并不是一个示例,因此您可能需要根据实际数据结构对其进行更新。

更新

上面将为您提供users 节点的值。

您需要通过on('value' 捕获once('child_added'forEach。我会举两个例子。

收听child_added

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

);

循环遍历value的示例:

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

);

这是一个包含两个样本的 jsbin:http://jsbin.com/fenavu/1/edit?js,console。请注意,此处的代码写出了ref.toString(),它为您提供了节点的完整 URL(因为 Firebase 中的每条数据都有自己唯一的 URL)。这可能是一种方便的方法来确定您的节点映射到哪个 URL。

【讨论】:

嘿弗兰克!谢谢,这是在正确的轨道上,但这并没有捕捉到电子邮件的位置,它只是将“gold:total”添加到基本“用户”,而不是添加到特定用户。我是否遗漏了一些东西来确保它在该用户下更新,而不仅仅是一般的“用户”? 是的,我想知道这一点。您可能应该使用once('child_added' 进入孩子。但是既然您显然认为电子邮件地址是识别用户的好方法,那么为什么不直接将电子邮件地址也用作用户节点的名称呢?这将使线路恢复到更易于管理的ref.child('users').child(emailAddress).update(... 嘿弗兰克!只需将 'value' 切换为 'child_added' 就完美了! (你的第一个例子)。万分感谢!我想如果我只是将电子邮件用作用户的节点,我仍然会遇到同样的问题,因为我需要在当前用户以及不同的用户下进行更新。感谢您的帮助! 我看不出这个答案如何解决问题。您肯定不想授予用户写入权限以在其他用户的帐户上设置总计等吗?有关使用观察到的基于请求的方法,请参阅下面的答案。您可以在 Node 脚本中处理任何类型的请求,并以管理员身份对目标用户进行相应的更改。 问题不是“如何在玩家之间安全地转账?”,而是“为什么我的代码找不到其他用户?”,所以我回答了这个问题。如果您关心安全性,这是一个更好的解决方案,不需要托管您自己的服务器:github.com/tomlarkworthy/firesafe/wiki/Send-Item【参考方案2】:

您可以通过电子邮件存储用户,其中@ 替换为_. 替换为-

所以你在 Firebase 中有一个这样的 JSON 结构

users: 
   "bob_hoskins-com":  
      email: "bob@hoskins.com",
      date: "09-09-1999",
      gold: 
          ...
      
   

但是,我认为这不是解决这个问题的好方法。

我将创建一个节点服务,用于观察每个用户的 requests Firebase 位置以查找添加的孩子。节点服务然后将进行计算并将数据写入正确的路径,然后可以在处理后删除请求。

所以你的 Firebase 会有这样的规则


  "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"          
      
   

这是一些请求代码

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

【讨论】:

以上是关于使用 AngularJS 和 Firebase 与用户传输项目的主要内容,如果未能解决你的问题,请参考以下文章

使用 Angularjs 和 Firebase 构建聊天应用程序

如何在 AngularJS 和 FireBase 中进行简单的基于角色的授权?

登录时如何处理状态(Ionic、Firebase、AngularJS)?

得到错误的结果:从 AngularJS 访问 api 并使用 NodeJS 从 firebase 查询结果时出现时区问题

无法在 angularjs App 中配置 Firebase 云消息传递。

AngularJS Firebase 数据库通过复选框更新字段