2013-02-19 74 views
108

我试图创建一个应用程序,可以在特定用户帐户中获取/设置数据,并且我被Firebase诱惑。通过使用Firebase的名称属性获取用户

我遇到的问题是,我不知道如何针对特定用户的数据时,我的结构是这样的:

My data structure described by the text below.

online-b-cards 
    - users 
    - InnROTBVv6FznK81k3m 
     - email: "[email protected]" 
     - main: "Hello world this is a text" 
     - name: "Alex" 
     - phone: 12912912 

我环顾四周,我可以如果没有任何关于如何访问个人数据的信息,更不用说当他们将一些随机散列作为他们的ID时。

我将如何去基于他们的名字获取个人用户信息?如果有更好的方法,请告诉我!

+0

试试这个:http://stackoverflow.com/questions/32886546/how-to-get-all-child-list-from-firebase-android/36600791#36600791 – 2016-04-17 20:54:46

回答

133

此前,火力地堡需要你生成自己的索引下载在一个位置的所有数据,以查找和检索匹配一些子属性的元素(例如,所有用户name === "Alex")。

2014年10月,Firebase通过orderByChild()方法推出了新的查询功能,使您能够快速高效地完成此类查询。请参阅下面的更新答案。


向Firebase写入数据时,有几个不同的选项会反映不同的用例。在高层次,火力地堡是一个树形结构的NoSQL数据存储库,并提供了一些简单的图元用于管理数据的列表:

ref.child('users').child('123').set({ "first_name": "rob", "age": 28 }) 

  1. 了一个独特的,已知的关键火力点

  2. 追加到将自动按时间排序写有一个自动生成的密钥列表:

    ref.child('users').push({ "first_name": "rob", "age": 28 }) 
    
  3. 用于通过其独特的,已知路径中数据的变化:

    ref.child('users').child('123').on('value', function(snapshot) { ... }) 
    
  4. 过滤顺序在列表数据由属性值

    // Get the last 10 users, ordered by key 
    ref.child('users').orderByKey().limitToLast(10).on('child_added', ...) 
    
    // Get all users whose age is >= 25 
    ref.child('users').orderByChild('age').startAt(25).on('child_added', ...) 
    

With t他增加了orderByChild(),你不再需要为子属性查询创建自己的索引!例如,检索所有用户名为“亚历克斯”:在火力地堡

ref.child('users').orderByChild('name').equalTo('Alex').on('child_added', ...) 

工程师在这里。在将数据写入Firebase时,您有几个不同的选项可以反映不同的应用程序使用情况。由于Firebase是NoSQL数据存储区,因此您需要使用唯一键存储数据对象,以便您可以直接访问该项目,或者在特定位置加载所有数据并遍历每个项目以查找您正在查找的节点对于。有关更多信息,请参阅Writing DataManaging Lists

当您在火力地堡写数据时,您可以使用一个独特的,定义的路径(即a/b/c),或push数据到一个列表,它会生成一个唯一的ID(即a/b/<unique-id>),并允许你进行排序set数据和按时间查询该列表中的项目。您在上面看到的唯一ID是通过调用push将一个项目追加到列表online-b-cards/users生成的。

而不是在这里使用push,我建议使用set,并使用唯一密钥(例如用户的电子邮件地址)存储每个用户的数据。然后,您可以通过Firebase JS SDK导航至online-b-cards/users/<email>直接访问用户的数据。例如:

function escapeEmailAddress(email) { 
    if (!email) return false 

    // Replace '.' (not allowed in a Firebase key) with ',' (not allowed in an email address) 
    email = email.toLowerCase(); 
    email = email.replace(/\./g, ','); 
    return email; 
} 

var usersRef = new Firebase('https://online-b-cards.firebaseio.com/users'); 
var myUser = usersRef.child(escapeEmailAddress('[email protected]')) 
myUser.set({ email: '[email protected]', name: 'Alex', phone: 12912912 }); 

注意,由于火力地堡不引用允许某些字符(见Creating References),我们删除了.,并在上面的代码中,替换它。

+2

完美!感谢Rob的回应。爱火炉堡! – 2013-02-19 18:59:08

+0

我没有得到的是,当你做一个查询,你得到一个对象的id作为一个属性,在这种情况下,逃生电子邮件,值是您设置的对象。当然,如果你阅读一个列表,你不知道这个ID,那么......你应该怎样读取数据? – Sam 2014-03-31 07:42:25

+0

@Sam我不完全理解你的问题,但如果用一些示例代码提出一个单独的问题并解释你的用例,我很乐意提供帮助。 – 2014-03-31 14:37:20

2

这是一篇文章,帮助我尝试访问自动生成的唯一ID的帖子。 Access Firebase unique ids within ng-repeat using angularFire implicit sync

谢谢,bennlich(源):

火力地堡如同普通javascript对象。也许下面的例子可以让你走上正轨。

<div ng-repeat="(name, user) in users"> 
    <a href="" ng-href="#/{{name}}">{{user.main}}</a> 
</div> 

编辑:不能100%确定你想要的结果,但这里的多一点,可能引发一个“啊哈”的时刻。在您的Firebase仪表板中点击您正尝试访问的密钥。从那里你可以使用类似的东西:

var ref = new Firebase("https://online-b-cards.firebaseio.com/users/<userId>/name); 
    ref.once('value', function(snapshot) { 
     $scope.variable= snapshot.val(); 
}); 
+0

你好安东尼,感谢你提供了REST结构(?)的信息,它绝对是一个'aha'。回顾这篇文章,现在我清楚地意识到,我已经以一种尴尬的方式构建了我的数据,感谢这些提示,并且我会记住我的下一个基于Firebase的项目! – 2016-01-05 23:54:36

4

我认为最好的方法是基于Firebase提供的auth对象来定义用户的id。当我创建我的用户,我做的:

FirebaseRef.child('users').child(id).set(userData); 

这个id来自:

var ref = new Firebase(FIREBASE); 
var auth = $firebaseAuth(ref); 
auth.$authWithOAuthPopup("facebook", {scope: permissions}).then(function(authData) { 
    var userData = {}; //something that also comes from authData 
    Auth.register(authData.uid, userData); 
}, function(error) { 
    alert(error); 
}); 

的火力地堡身份验证服务将始终确保所有的供应商在UID被设置中一个唯一的ID。这样,总是在你将有auth.uid并且可以轻松地访问所需的用户进行更新,如:

FirebaseRef.child('users').child(id).child('name').set('Jon Snow'); 
4

您可以通过下面的代码抓住细节。

FirebaseDatabase database = FirebaseDatabase.getInstance(); 
DatabaseReference myRef = database.getReference("users"); 
myRef.orderByChild("name").equalTo("Alex").addListenerForSingleValueEvent(new ValueEventListener() {   
       @Override 
       public void onDataChange(DataSnapshot dataSnapshot) { 

        for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) { 
         Log.d(TAG, "PARENT: "+ childDataSnapshot.getKey()); 
         Log.d(TAG,""+ childDataSnapshot.child("name").getValue()); 
        } 
1

这是如何访问自动生成火力地堡唯一键: 数据结构: - OnlineBcards - 唯一键

database.ref().on("value", function(snapshot) { 
     // storing the snapshot.val() in a variable for convenience 
     var sv = snapshot.val(); 
     console.log("sv " + sv); //returns [obj obj] 

     // Getting an array of each key in the snapshot object 
     var svArr = Object.keys(sv); 
     console.log("svArr " + svArr); // [key1, key2, ..., keyn] 
     // Console.log name of first key 
     console.log(svArr[0].name); 
}, function(errorObject) { 
    console.log("Errors handled: " + errorObject.code); 
}); 
0

添加唯一的ID UR最简单和更好的方法数据库根据认证用户是这样的:

private FirebaseAuth auth; 

String UId=auth.getCurrentUser().getUid(); 

FirebaseDatabase database = FirebaseDatabase.getInstance(); 
DatabaseReference myRef = database.getReference("Users"); 

User user = new User(name,email,phone,address,dob,bloodgroup); 

myRef.child(UId).setValue(user); 

该UID将是一个唯一的ID为特定的认证电子邮件/用户

+3

这并没有解决问题。问题是如何获取和设置特定用户帐户中的数据。由于* user *不是有效的参数,因此您的代码会创建一个用户帐户并且实际上无效,因为您无法.setValue(用户)。 – Jay 2017-03-31 19:35:38

0

最简单的方法是停止使用.push(){}

功能,这将产生随机密钥。但改为使用.update(){}函数,您可以指定孩子的名称而不是随机密钥。