【问题标题】:Querying usernames through database to make sure identical one doesn't exist when user wants to change their existing username通过数据库查询用户名以确保当用户想要更改其现有用户名时不存在相同的用户名
【发布时间】:2020-05-25 11:55:47
【问题描述】:

我想做的是当用户决定编辑他们的用户名时,我想通过数据库运行查询,确保他们选择的用户名没有被使用。在大多数情况下,我认为我做对了,我运行一个 for 循环来查看已添加到数据库中的所有用户名,如果匹配,则显示 Toast 消息。

问题是它显示了Toast 消息,但即使用户名正在使用,它仍然会更改用户名。我知道这是简单的代码,但我不知道我做错了什么。有人介意看看吗?我认为问题出在mUsername,因为我在updateProfile(); 方法中设置了它,但如果我设置新的mUserName1,我不能因为它是EditText 而不是String

EditProfileActivity

public class EditProfileActivity extends AppCompatActivity {

    ImageView mClose, mCheckmark, mImageProfile;
    TextView mChangePhoto;
    MaterialEditText mName, mUsername, mBio;

    private String mUsername1;
    private String mUsername2;

    FirebaseUser mFirebaseUser;

    private Uri mImageUri;
    StorageReference mStorageReference;

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

        mClose = findViewById(R.id.close);
        mCheckmark = findViewById(R.id.post_checkmark);
        mImageProfile = findViewById(R.id.image_profile);
        mChangePhoto = findViewById(R.id.text_view_change_profile_picture);
        mName = findViewById(R.id.fullname);
        mUsername = findViewById(R.id.username);
        mBio = findViewById(R.id.bio);

        mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        mStorageReference = FirebaseStorage.getInstance().getReference("uploads");

        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users").child(mFirebaseUser.getUid());
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                User user = dataSnapshot.getValue(User.class);
                if (user != null) {
                    mName.setText(user.getFullname());
                    mUsername.setText(user.getUsername().toLowerCase());
                    mBio.setText(user.getBio());
                    Glide.with(getApplicationContext()).load(user.getImageurl()).into(mImageProfile);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        mClose.setOnClickListener(v -> new AlertDialog.Builder(EditProfileActivity.this)
                .setMessage("Exit without saving changes?")
                .setPositiveButton("Yes", (dialog, which) -> {
                    finish();
                }).setNegativeButton("No", null).show());

        mChangePhoto.setOnClickListener(v -> CropImage.activity()
                .setAspectRatio(1, 1)
                .setCropShape(CropImageView.CropShape.OVAL)
                .start(EditProfileActivity.this));

        mImageProfile.setOnClickListener(v -> CropImage.activity()
                .setAspectRatio(1, 1)
                .setCropShape(CropImageView.CropShape.OVAL)
                .start(EditProfileActivity.this));

        mCheckmark.setOnClickListener(v -> {

            String str_name = mName.getText().toString();
            String str_username = mUsername.getText().toString();
            String str_bio = mBio.getText().toString();

            if (TextUtils.isEmpty(str_username) || TextUtils.isEmpty(str_bio) || TextUtils.isEmpty(str_name)) {
                Toast.makeText(this, "Please fill in all fields", Toast.LENGTH_SHORT).show();
            } else if (str_username.length() > 20) {
                Toast.makeText(this, "Username cannot contain more than 20 characters", Toast.LENGTH_SHORT).show();
            } else {
                updateProfile(mName.getText().toString(), mUsername.getText().toString().toLowerCase(), mBio.getText().toString());
            }
        });
    }

    private void updateProfile(String fullname, String username, String bio) {
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users").child(mFirebaseUser.getUid());

        mUsername1 = username.replaceAll("\\s+", "");
        mUsername1 = username.replaceAll("[^\\w]", "");

        DatabaseReference reference1 = FirebaseDatabase.getInstance().getReference("Users");
        reference1.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    User user = snapshot.getValue(User.class);
                    if (user != null) {
                        if (user.getUsername().equals(mUsername1)) {
                            Toast.makeText(EditProfileActivity.this, "That username is already in use", Toast.LENGTH_SHORT).show();
                        } else {
                            HashMap<String, Object> hashMap = new HashMap<>();
                            hashMap.put("fullname", fullname);
                            hashMap.put("username", mUsername1.toLowerCase());
                            hashMap.put("bio", bio);

                            reference.updateChildren(hashMap);
                        }
                    }
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    在 toast 消息后添加一个 break 语句。当您从数据快照中循环用户对象列表时。此外,您需要在保存之前搜索所有用户对象。

     if (user.getUsername().equals(mUsername1)) {
                            Toast.makeText(EditProfileActivity.this, "That username is already in use", Toast.LENGTH_SHORT).show();
    break;
                        }
    

    更新代码 -

           DatabaseReference reference1 = FirebaseDatabase.getInstance().getReference("Users");
                reference1.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
          boolean ifUserNameExist = false;
                        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                            User user = snapshot.getValue(User.class);
                            if (user != null) {
                                if (user.getUsername().equals(mUsername1)) {
                                    Toast.makeText(EditProfileActivity.this, "That username is already in use", Toast.LENGTH_SHORT).show();
                               ifUserNameExist = true;
                                } 
                            }
                        }
    if(!ifUserNameExist){
       HashMap<String, Object> hashMap = new HashMap<>();
                                    hashMap.put("fullname", fullname);
                                    hashMap.put("username", mUsername1.toLowerCase());
                                    hashMap.put("bio", bio);
    
                                    reference1.updateChildren(hashMap);
    }
                    }
    
                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {
    
                    }
                });
    

    【讨论】:

    • 哈哈,这很容易。你能解释一下为什么吗?那个合法的让它工作......很容易......但为什么我必须添加休息?
    • 保存前循环吗?所以我必须更多地改变它,或者它是好的?那么在for循环之外添加HashMap呢?
    • @JMB 假设您已经有 4 个用户,分别是 username1、username2、username3、username4。现在你正在循环这 4 个对象。现在,username1 想要将用户名更新为 username2。在第二个循环中,if 条件得到满足,因此您会看到 toast 消息。现在第三个循环条件不满足并且用户数据被更新。希望清楚。
    • @JMB 更新了答案。那应该有帮助。如果没有尝试在代码中添加 log.d 语句以了解您到底在哪里搞砸了。还将引用变量更新为reference1。
    • 谢谢兄弟!现在使用我刚刚实现的布尔标志效果更好。感谢您的帮助!
    猜你喜欢
    • 2020-09-12
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多