Android Firebase: пользовательские данные в реальном времени удаляются при повторном входе пользователя
Я использую проверку подлинности Google Firebase для входа в систему, и у меня был список точек данных, связанных с пользователем. Пользователь заполняет свои данные, создавая элементы во время сеанса, вошедшего в систему, и они обновляют список в Firebase, который хранится под его идентификатором пользователя в ссылке "пользователь" RTDB.
Ключевые моменты:
- Когда я выхожу, данные сохраняются.
- Когда я снова вхожу в систему, UID совпадает в RTDB
- Когда я снова вхожу, пользовательский список удаляется.
Как я могу сохранить данные в 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
РЕДАКТИРОВАТЬ: у меня было впечатление, что функция записи не будет перезаписывать существующие данные. Как я могу добавить к пользователям ссылки на данные конкретного пользователя при входе в Google, не перезаписывая какую-либо информацию, которую они уже имеют?
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("\\");
}
3 ответа
Чтобы проверить, существует ли пользователь в базе данных Firebase Realtime, перед его добавлением при входе / регистрации пользователя в 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) {}
});
}
Отсюда я получил подсказку и руководство по ответу @Prisoner.
Проблема в вашем методе writeNewUser(). Похоже, что это вызывается каждый раз, когда пользователь проходит аутентификацию, а не только в первый раз (что предложил бы "новый пользователь").
У вас есть три варианта:
Перестройте ваш код, чтобы проверить, существует ли пользователь, а затем записать информацию о пользователе, только если он не существует.
Перестройте ваш код, чтобы обновлялись только измененные данные.
Перестройте ваши данные так, чтобы информация о пользователях сохранялась на один уровень глубже - таким образом, перезапись ее не меняет ни одного из соседних узлов.
Вы могли бы реализовать 3 с чем-то вроде:
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);
}
Вы перезаписываете данные, потому что используете setValue()
метод. Вместо того, чтобы использовать этот метод, используйте updateChildren()
метод и ваша проблема будет решена.
Надеюсь, поможет.