Java 检查 Firebase 数据库中是否存在特定值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47893328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 02:43:08  来源:igfitidea点击:

Checking if a particular value exists in the Firebase database

javaandroidfirebasefirebase-realtime-database

提问by Nick

I am making an Android application using Firebaserealtime database. When a new user registers on my app, that user's data is saved in the Firebase database.

我正在使用Firebase实时数据库制作 Android 应用程序。当新用户在我的应用上注册时,该用户的数据会保存在 Firebase 数据库中。

A user has to provide the following details to register:

用户必须提供以下详细信息才能注册:

  1. Full Name
  2. Email
  3. Username
  4. Password
  1. 全名
  2. 电子邮件
  3. 用户名
  4. 密码

Database Structure

数据库结构

enter image description here

在此处输入图片说明

Whenever a new user tries to register, I have to make sure that each user's username is unique so I check the database if the usernameentered by the user already exists in the database or not.

每当新用户尝试注册时,我必须确保每个用户的用户名都是唯一的,因此我会检查数据库username中用户输入的用户名是否已存在于数据库中。

To do this, I wrote the following method:

为此,我编写了以下方法:

private boolean usernameExists(String username) {
     DatabaseReference fdbRefer = FirebaseDatabase.getInstance().getReference("Users/"+username);
     return (fdbRefer != null);
}

My logic behind this method is that if getReferencemethod cannot find reference to the specified path, it will return null so that I can return whether fdbReferis nullor not. If fdbReferis null, then it means that usernamedoesn't exist in the database.

我的这种方法背后的逻辑是,如果getReference方法无法找到引用到指定的路径,它会返回null,这样我可以返回是否fdbRefernull或不是。如果fdbRefernull,则表示username数据库中不存在。

Problem

问题

Problem with this method is that it always returns truewhether the entered usernameexists in the database or not. Which led me to believe that fdbReferis never null.

这种方法的问题在于它总是返回true输入username的数据是否存在于数据库中。这让我相信fdbRefer永远不会null

This brings me to my question...

这让我想到了我的问题......

Question

What does getReferencemethod return when it can't find the specified path in the firebasedatabase and what's the correct way to check if the usernamealready exists in the database or not?

什么getReference方法返回时,它无法找到在指定的路径firebase数据库,什么是检查是否正确的方法username已经在数据库中存在与否?

采纳答案by Alex Mamo

To check a existence of user, please use the below code:

要检查用户是否存在,请使用以下代码:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userNameRef = rootRef.child("Users").child("Nick123");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if(!dataSnapshot.exists()) {
            //create new user
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
    }
};
userNameRef.addListenerForSingleValueEvent(eventListener);

You can also use a Query to achieve the same thing like this:

您还可以使用 Query 来实现相同的功能:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Users").orderByChild("userName").equalTo("Nick123");
query.addValueEventListener(/* ... */);

This is another approach which is looping through the entire Usersnode but is not just using a direct reference to a single user. This option is more likely to be used when you are using as a unique identifier beteeen users the uidinstead of the user name (as you do right now). So if your database structure might looks similar to this:

这是另一种方法,它循环遍历整个Users节点,但不只是使用对单个用户的直接引用。当您将用户用作唯一标识符uid而不是用户名(就像您现在所做的那样)时,更有可能使用此选项。因此,如果您的数据库结构可能与此类似:

Firebase-root
   |
   --- Users
        |
        --- uid
             |
             --- userName: "Test User"
             |
             --- emailAddress: "[email protected]"

The second solution is the recommended one.

第二种解决方案是推荐的解决方案。

There is also another solution which involves youto create another node named userNames, in which you can hold only the unique user names. Please also find below the corresponding security rules:

还有另一种解决方案,它涉及您创建另一个名为 的节点userNames,您只能在其中保存唯一的用户名。另请在下面找到相应的安全规则:

"Users": {
  "$uid": {
    ".write": "auth !== null && auth.uid === $uid",
    ".read": "auth !== null && auth.provider === 'password'",
    "userName": {
      ".validate": "
        !root.child('userNames').child(newData.val()).exists() ||
        root.child('userNames').child(newData.val()).val() == $uid"
    }
  }
}

But since in this case, your user name is already the name of the node, I recommend you go ahead with the first one.

但由于在这种情况下,您的用户名已经是节点的名称,我建议您继续使用第一个。

回答by sivaram636

Instead of checking for the exists of the reference you can use orderBy query to check whether username exists already

您可以使用 orderBy 查询来检查用户名是否已经存在,而不是检查引用是否存在

orderByChild('username').equalTo(username) query would return data if some data already exists else it will return null.

orderByChild('username').equalTo(username) 如果某些数据已经存在,则查询将返回数据,否则将返回空值。

回答by Amit Joshi

Check it like this...

像这样检查...

    fdbRefer.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exist() {
//username exist
}
else {
//username doesn't exist
}
}
});

回答by Peter Haddad

Try this:

尝试这个:

DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("Users");
ref.orderByChild("username").equalTo(Nick123).addValueEventListener(new ValueEventListener(){
  @Override
  public void onDataChange(DataSnapshot dataSnapshot){
      if(dataSnapshot.exist() {
         //username exist
          }
        }

You have to use orderbychildand equaltoto check the value if it is there. If you dont use orderbychildand equaltothen it will just check if usernamechild node is there and doesnt care about the value.

您必须使用orderbychildequalto检查该值是否存在。如果你不使用orderbychild,并equalto然后它只是检查,如果username子节点是存在的,不关心有关的价值。

this orderByChild("username").equalTo(Nick123)is like saying:

orderByChild("username").equalTo(Nick123)就像说:

WHERE username=Nick123

回答by vivek kumar

Since you have already got a solution to your problem, I will try to explain why your code was not working.

由于您已经找到了问题的解决方案,我将尝试解释为什么您的代码不起作用。

 DatabaseReference fdbRefer = FirebaseDatabase.getInstance().getReference("Users/"+username);
 DatabaseReference fdbRefer = FirebaseDatabase.getInstance().getReference("Users/"+username);

You might be thinking that in the above statement fdbReferwill be null if "Users/"+username is not present in the database.
But actually, this statement will only store a path to the specified field in getReference(). So when you check for fdbRef!=null, it is always true because fdbReferwill hold value something like 'https://.firebase.com/Users/Nick123.

您可能会认为,fdbRefer如果数据库中不存在“Users/”+username ,则上述语句将为空。
但实际上,这个语句只会存储到getReference(). 因此,当您检查 时fdbRef!=null,它总是正确的,因为fdbRefer它将持有类似“https://.firebase.com/Users/Nick123”的值。

回答by Muhammad Hashim Shafiq

Works Perfectly for me

非常适合我

DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
        Query query = reference
                .child(getString(R.string.dbname_users))
                .orderByChild("username")
                .equalTo(username);
        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if(dataSnapshot.getChildrenCount()>0) {
                    //username found

                }else{
                    // username not found
                }

            }
            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });