Android Firebase: User-specific real-time data is removed when user logs back in

不打扰是莪最后的温柔 提交于 2019-12-12 04:57:50

问题


I am using Firebase Google authentication for login, and I had a list of data points associated with a user. The user populates their data by creating elements in a logged-in session, and these update a list in Firebase that is stored under their uid in a 'user' reference of the RTDB.

Key points:

  1. When I log out, the data persists.
  2. When I log back in, the uid is the same in the RTDB
  3. When I log back in, the user-specific list is deleted.

How can I make the data persist in the RTDB?

UserDataListActivity

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.signout_button:
            FirebaseAuth.getInstance().signOut();
            Log.i(TAG, "User allegedly logged out.");
            Intent backToLogin = new Intent(UserDataListActivity.this, LoginActivity.class);
            startActivity(backToLogin);
            finish();
            break;
    }
}

LoginActivity

EDIT: I was under the impression that the write function would not overwrite the existing data. How can I add to the users reference a specific user's data upon Google login without overwriting whatever information they already have?

private void onAuthSuccess(FirebaseUser user) {
    String username = usernameFromEmail(user.getEmail());
    String[] names = firstAndLastNameFromDisplayName(user.getDisplayName());

    // Write new user
    writeNewUser(user.getUid(), names, username, user.getEmail(), user.getUid());

    // Go to MainActivity
    Intent startMainActivity = new Intent(LoginActivity.this, MainActivity.class);
    startActivity(startMainActivity);
    finish();
}
private String usernameFromEmail(String email) {
    if (email.contains("@")) {
        return email.split("@")[0];
    } else {
        return email;
    }
}
private String[] firstAndLastNameFromDisplayName(String fullName) {
    if (fullName != null) {
        if (fullName.contains(" ")) {
            return new String[]{fullName.split(" ")[0], fullName.split(" ")[1]};
        } else {
            return new String[]{fullName, "emptyLastName"};
        }
    } else {
        return new String[]{"defaultfirst","defaultlast"};
    }
}
private void writeNewUser(String userId, String[] names, String username, String email,String uid) {
    User user = new User(username,names[0],names[1], email, uid);
    myUsers.child(userId).setValue(user);
}

private boolean isEmailValid(String email) {
    return email.contains("@");
}

private boolean isPasswordValid(String password) {
    return (password.length() > 4) && !password.contains("\\");
}


回答1:


The problem is in your writeNewUser() method. It looks like this is called every time the user authenticates - not just the first time (which the "new user" would suggest).

You have three options:

  1. Restructure your code so you check to see if the user exists, and then only writes the user info if it does not exist.

  2. Restructure your code so only changed data is updated.

  3. Restructure your data so user information is stored one level deeper - thus overwriting it doesn't change any of the sibling nodes.

You could implement 3 with something like:


private void writeNewUser(String userId, String[] names, String username, String email,String uid) {
    User user = new User(username,names[0],names[1], email, uid);
    myUsers.child(userId).child("userInfo").setValue(user);
}



回答2:


You are overwriting the data because you are using the setValue() method. In stead of using that method, use updateChildren() method and your problem will be solved.

Hope it helps.




回答3:


To check if a user exists in Firebase Realtime Database before adding one upon user login/registration in Android:

private void writeNewUser(final String userId, String[] names, String username, String email,String uid) {
    final User user = new User(username,names[0],names[1], email, uid);
    myUsers.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (!dataSnapshot.hasChild(userId)) {
                myUsers.child(userId).setValue(user);
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });

}

I got the tip from here and the guidance of @Prisoner's answer.



来源:https://stackoverflow.com/questions/44621301/android-firebase-user-specific-real-time-data-is-removed-when-user-logs-back-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!