使用Firebase按名称获取用户属性


129

我正在尝试创建一个应用程序,可以在其中获取/设置特定用户帐户中的数据,并且被Firebase吸引。

我遇到的问题是,当我的结构看起来像这样时,我不知道如何定位特定的用户数据:

我的数据结构如下文所述。

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

我环顾四周,当给他们一些随机散列作为ID时,我真的找不到任何有关如何访问单个数据的信息。

我将如何根据用户名获取单个用户信息?如果有更好的方法,请告诉我!


Answers:


156

以前,Firebase要求您生成自己的索引在某个位置下载所有数据,以查找和检索与某些子属性匹配的元素(例如,所有具有的用户name === "Alex")。

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


在将数据写入Firebase时,您有几个不同的选项,它们将反映不同的用例。从总体上讲,Firebase是树结构的NoSQL数据存储,并提供了一些用于管理数据列表的简单原语:

  1. 使用已知的唯一密钥写入 Firebase:

    ref.child('users').child('123').set({ "first_name": "rob", "age": 28 })
    
  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', ...)
    

通过添加orderByChild(),您不再需要为查询子属性创建自己的索引!例如,要检索所有名称为“ Alex”的用户:

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

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

在Firebase中写入数据时,您可以set使用唯一的,已定义的路径(即a/b/cpush将数据添加到列表中,也可以将数据放入列表中,这将生成唯一的ID(即a/b/<unique-id>),并允许您按时间对列表中的项目进行排序和查询。您在上方看到的唯一ID是通过调用push将项目附加到列表中生成的online-b-cards/users

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

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('hello@hello.com')) 
myUser.set({ email: 'hello@hello.com', name: 'Alex', phone: 12912912 });

请注意,由于Firebase不允许引用中使用某些字符(请参阅创建引用),因此我们删除了,.,在上面的代码中将其替换为。


1
@RobDiMarco您对斯蒂芬在下面发布的问题有答案吗?
查尔斯·汉

2
嘿@RobDiMarco。虽然您建议使用电子邮件地址作为ID的依据仍然有效,但可能值得扩大答案以指向新orderByChild功能。鉴于此答案经常作为相关/相关答案出现,因此人们一定会关注它,并且应该意识到新的查询功能。
Frank van Puffelen 2014年

1
@FrankvanPuffelen好主意-感谢您的来信。我今天要更新。
罗布·迪马科

1
@Ced不幸的是,我无法评论作品中的内容。我保证我们会努力工作(这始终是事实),但不能提供具体细节。Database API在某些方面确实是限制性的,我们故意这样做只是为了公开可以保证一定性能水平的方法。例如,这就是为什么我们不公开在整个列表上运行操作的方法的原因。适用于高级用户的文档上的公平点。如有疑问,请尝试与我们的Google 网上论坛进行详细对话:groups.google.com/forum/# ! forum/firebase-talk团队在这里非常活跃!
Rob DiMarco

1
@RobDiMarco真是太好了。昨天我看到了Firebase的功能,并整日大肆宣传,因为我认为Firebase可以改变游戏规则,并且将彻底改变后端。认真地说,我可以教一个从来没有编写过代码的人来维护Firebase的后端。那真是太神奇了,也很吓人。干杯
Ced

5

您可以通过以下代码获取详细信息。

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

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

Firebase身份验证服务将始终确保在其所有提供程序中将唯一ID设置为uid。这样一来,您将始终拥有auth.uid,并可以轻松访问所需的用户以对其进行更新,例如:

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

2

这是对一篇帖子的解释,它在尝试访问自动生成的唯一ID时对我有所帮助。使用angularFire隐式同步在ng-repeat中访问Firebase唯一ID

谢谢,本利希(来源):

Firebase的行为类似于普通的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();
});

安东尼您好,谢谢您提供有关REST结构的信息(?),它确实给人留下了深刻的印象。回顾这篇文章,现在我很清楚,我以一种尴尬的方式来构造数据,感谢您的提示,在下一个基于Firebase的项目中,我会牢记在心!
理查德·班福德

2

这是在Firebase中访问自动生成的唯一键的方法: 数据结构:-OnlineBcards-UniqueKey

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

1

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

函数将生成该随机密钥。但是,请使用可以在.update(){}其中指定子项名称的函数,而不要使用随机键。


1

检索数据:

在您的数据库中,您使用的是使用生成的随机ID push(),因此,如果您要检索数据,请执行以下操作:

在Android App中使用Firebase:

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users");
ref.addListenerForSingleValueEvent(new ValueEventListener() {           
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for (DataSnapshot datas : dataSnapshot.getChildren()) {
                    String name=datas.child("name").getValue().toString();
                }
             }

            @Override
           public void onCancelled(DatabaseError databaseError) {
          }
     });

在Javascript中使用Firebase:

  firebase.database().ref().child("users").on('value', function (snapshot) {
   snapshot.forEach(function(childSnapshot) {
    var name=childSnapshot.val().name;
  });
});

在这里,您有快照(数据位置)在 users然后在所有随机ID内循环并检索名称。


检索特定用户的数据:

现在,如果您只想检索特定用户的信息,则需要添加一个查询:

在Android App中使用Firebase:

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users");
Query queries=ref.orderByChild("name").equalTo("Alex");
queries.addListenerForSingleValueEvent(new ValueEventListener() {...}

将Firebase与Javascript结合使用

firebase.database().ref().child("users").orderByChild("name").equalTo("Alex").on('value', function (snapshot) {
   snapshot.forEach(function(childSnapshot) {
      var name=childSnapshot.val().name;
   });
});

使用orderByChild("name").equalTo("Alex")就像是说,where name="Alex"所以它将检索与Alex有关的数据。


最好的办法:

最好的方法是使用Firebase身份验证,从而为每个用户生成一个唯一的ID,并使用它代替随机ID push(),这样您就不必遍历所有用户,因为您拥有ID并且可以轻松访问它。

首先,需要登录用户,然后您可以检索唯一的ID并附加一个侦听器以检索该用户的其他数据:

在Android上使用Firebase:

DatabaseReference ref = FirebaseDatabase.getInstance().getReference("users");
String uid = FirebaseAuthentication.getInstance().getCurrentUser().getUid();

ref.child(uid).addListenerForSingleValueEvent(new ValueEventListener() {
          @Override
         public void onDataChange(DataSnapshot dataSnapshot) { 
           String name=dataSnapshot.child("name").getValue().toString(); 
   }
         @Override
       public void onCancelled(DatabaseError databaseError) {
      }
 });

将Firebase与Javascript结合使用:

    var user = firebase.auth().currentUser;
    var uid=user.uid;

    firebase.database().ref().child("users").child(uid).on('value', function (snapshot) {
     var name=snapshot.val().name;
   });
 

0

根据经过身份验证的用户向您的数据库添加唯一ID的最简单,更好的方法是:

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
那没有解决这个问题。问题是如何在特定的用户帐户中获取和设置数据。您的代码创建了一个用户帐户,实际上是无效的,因为您不能.setValue(user),因为user不是有效的参数。
杰伊
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.