【问题标题】:Get users by name property using Firebase使用 Firebase 按名称属性获取用户
【发布时间】:2013-02-04 12:07:45
【问题描述】:

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

我遇到的问题是,当我的结构如下所示时,我不知道如何定位特定用户数据:

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

我环顾四周,我真的找不到任何关于如何访问个人数据的信息,更不用说当他们被赋予一些随机哈希作为他们的 ID 时。

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

【问题讨论】:

标签: firebase firebase-realtime-database


【解决方案1】:

以前,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. 过滤排序列表中的数据key属性值

    // 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 数据存储,因此您需要使用唯一键存储数据对象,以便您可以直接访问该项目或在特定位置加载所有数据并遍历每个项目以找到您正在寻找的节点.请参阅Writing DataManaging Lists 了解更多信息。

当您在 Firebase 中写入数据时,您可以使用唯一的已定义路径(即 a/b/cset 数据,或者将 push 数据写入一个列表,这将生成一个唯一 id(即 a/b/<unique-id> ) 并允许您按时间对该列表中的项目进行排序和查询。您在上面看到的唯一 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('hello@hello.com')) 
myUser.set({ email: 'hello@hello.com', name: 'Alex', phone: 12912912 });

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

【讨论】:

  • @RobDiMarco 你对斯蒂芬下面发布的问题有答案吗?
  • 嘿@RobDiMarco。虽然您使用电子邮件地址作为 id 基础的建议仍然有效,但可能值得扩展您的答案以指向新的 orderByChild 功能。鉴于此答案经常作为相关/相关答案出现,人们一定会查看它并且应该了解新的查询功能。
  • @FrankvanPuffelen 好主意 - 感谢您的注意。我今天会更新这个。
  • @Ced 不幸的是,我无法评论正在进行的工作。我保证我们正在努力工作(这一直是真的),但不能给出具体细节。数据库 API 在某些方面确实是有限制的,我们故意这样做是为了只公开我们可以保证一定性能水平的方法。这就是为什么我们不公开一个方法来对整个列表运行操作,例如。高级用户文档的公平点。如有疑问,请尝试我们的 Google 群组进行详细对话:groups.google.com/forum/#!forum/firebase-talk 该团队在这里非常活跃!
  • @RobDiMarco 很高兴听到这个消息。我昨天看到了 Firebase 的功能,一整天都在大肆宣传,因为我认为 Firebase 改变了游戏规则,并且即将彻底改变后端。说真的,我可以教一个从未编写过代码的人在 Firebase 上维护一个后端。这太神奇了,也太可怕了。干杯
【解决方案2】:

检索数据:

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

在 Android 应用中使用 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 应用中使用 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;
   });
 

【讨论】:

    【解决方案3】:

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

    生成随机密钥的函数。但改为使用.update(){} 函数,您可以在其中指定孩子的姓名,而不是使用随机密钥。

    【讨论】:

      【解决方案4】:

      根据经过身份验证的用户向您的数据库添加唯一 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

      【讨论】:

      • 这并没有解决问题。问题是如何获取和设置特定用户帐户中的数据。您的代码创建了一个用户帐户,实际上是无效的,因为您不能 .setValue(user) 因为 user 不是有效参数。
      【解决方案5】:

      这是在 Firebase 中访问自动生成的唯一键的方法: 数据结构: - 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);
      });
      

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

          我认为最好的方法是根据 Firebase 提供的身份验证对象来定义用户的 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');
          

          【讨论】:

            【解决方案8】:

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

            谢谢,bennlich(来源):

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

            【讨论】:

            • 您好 Anthony,感谢您提供有关 REST 结构 (?) 的信息,它确实让您感到“啊哈”。回顾这篇文章,我现在清楚地知道我的数据结构有点尴尬,感谢您的提示,我会在下一个基于 firebase 的项目中记住它!
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-01-08
            • 2018-10-28
            • 2023-03-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多