Java 如果用户不存在,如何创建该用户?

Java 如果用户不存在,如何创建该用户?,java,android,firebase,Java,Android,Firebase,当用户第一次在应用程序中使用您的google帐户登录时,我执行此活动是为了在数据库中创建用户。它正在工作,但正在数据库中创建多个用户,我不知道为什么 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_account); mAuth = FirebaseAuth

当用户第一次在应用程序中使用您的google帐户登录时,我执行此活动是为了在数据库中创建用户。它正在工作,但正在数据库中创建多个用户,我不知道为什么

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_account);

    mAuth = FirebaseAuth.getInstance();
    mAuthListener = new FirebaseAuth.AuthStateListener() {

        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {

            if (firebaseAuth.getCurrentUser() == null) {
                goLogInScreen();
            } else {
                final String userGoogleEmail = firebaseAuth.getCurrentUser().getEmail();
                databaseUser.orderByChild("userEmail").equalTo(userGoogleEmail).addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (dataSnapshot.exists()) {
                            //User already exists
                        } else {
                            //Can create new user
                            String id = databaseUser.push().getKey();
                            User user = new User(id, userGoogleEmail, null);
                            databaseUser.child(id).setValue(user);
                        }
                    }

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

之所以会发生这种情况,是因为您使用的是由
push()
方法生成的密钥作为标识符,而不是另一个标识符,这实际上是在再次创建用户,即使数据库中存在该用户

我建议您做的是,稍微改变一下在数据库中保存数据的逻辑。因此,为了解决您的问题,我建议您使用
电子邮件地址作为标识符来代替该键,因为它也是唯一的。您的数据库应如下所示:

Firebase-database
     |
     --- Users
          |
          --- jon@email,com
          |      |
          |      --- //data
          |
          --- jack@email,com
                 |
                 --- //data
DatabaseReference usersRef = usersDatabaseReference.child(userEmail);
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if (!dataSnapshot.exists()) {
            //create user
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(valueEventListener);
正如您可能看到的,我使用
(逗号)而不是
(点)将电子邮件地址保存在Firebase数据库中

name@email.com -> name@email,com

这是因为Firebase不允许在密钥名称中使用类似
的符号。因此,要存储这样的值,需要编码的电子邮件。为了实现这一点,我建议您使用以下方法:

String encodeUserEmail(String userEmail) {
    return userEmail.replace(".", ",");
}

String decodeUserEmail(String userEmail) {
    return userEmail.replace(",", ".");
}
要验证用户是否存在,只需将a listenr放在
Users
节点上,并对dataSnapshot对象使用
exists()
方法,如下所示:

Firebase-database
     |
     --- Users
          |
          --- jon@email,com
          |      |
          |      --- //data
          |
          --- jack@email,com
                 |
                 --- //data
DatabaseReference usersRef = usersDatabaseReference.child(userEmail);
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if (!dataSnapshot.exists()) {
            //create user
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(valueEventListener);

希望这能解决您的问题。

您的意思是,它只在数据库中没有现有用户时运行,但当它运行一次时,它会在数据库中为该用户创建多个条目?如果是这样的话,它在数据库中创建用户的次数是多少?是的,只有在数据库中没有用户的情况下,在运行时,有时我尝试过,在4、2和6次之间变化@GEREMOConsider使用共享首选项,而不是依赖getCurrentUser(),这可能是firebase上的同步问题!如果用户首次登录,请在SharedReference中存储一个值。如果用户再次访问该应用程序,请尝试检索SharedReference。