#android #firebase
#Android #firebase
Вопрос:
В настоящее время я работаю над приложением родительского контроля, чего я хотел бы добиться, так это того, что родитель и потомок могут входить в систему с одним и тем же адресом электронной почты на разных устройствах, и я также хочу добиться функции автоматического входа в систему, когда родитель открывает приложение, оно напрямую загружает родительскую активность, если дочерний элемент затем загружает дочернюю активность.
Но теперь проблема в том, что я не могу этого сделать, я понятия не имею, как идентифицировать их обоих, поскольку они используют один и тот же адрес электронной почты. Ранее я мог выполнить автоматический вход в систему для родительского пользователя с помощью FirebaseAuth.getCurrentUser(), а затем проверить тип пользователя в firestore. Но теперь я ничего не могу проверить, чтобы определить, является ли пользователь дочерним или родительским.
Что я пробовал:
- Создайте поле вызова «дочерний», когда пользователь (Джон) войдет в систему как дочерний, обновите поле «TRUE» (скажем так), когда Джон выйдет из приложения и снова войдет в систему, система начнет проверять, является ли UserType == «parents», если нет, то только он проверит, является ли child == «TRUE». Таким образом, дочерний пользователь всегда будет автоматически входить в ParentActivity, но не в ChildActivity.
Есть ли какой-нибудь способ достичь этого? Надеюсь, вы, ребята, понимаете, в чем моя проблема. На прикрепленном изображении показано, как я ранее добился автоматического входа в систему для родителя. Заранее спасибо!
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Transparent Status Bar
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
ButterKnife.bind(this);
//FirebaseApp.initializeApp(this.getBaseContext());
firebaseAuth = FirebaseAuth.getInstance();
clearUserType();
}
// Hide keyboard after user clicking somewhere
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.
INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
}
@OnClick(R.id.LoginButton)
public void login(){
progressBar.setVisibility(View.VISIBLE);
if (!Utils.isValidEmail(email, emailLayout) | !Utils.hasEmail(email, emailLayout) | !Utils.hasPassword(password, passwordLayout)){
progressBar.setVisibility(View.INVISIBLE);
return;
}
startSignIn(email.getText().toString(), password.getText().toString());
}
@OnClick(R.id.SignUpButton)
public void signUpScreen(){
Intent signup = new Intent(this, SignUpActivity.class);
startActivity(signup);
finish();
}
@OnTextChanged(value = R.id.LoginEmailText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
public void emailChanged(CharSequence s){
if(!(s.length() < 1)){
emailLayout.setError(null);
}
}
@OnTextChanged(value = R.id.LoginPasswordText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
public void passwordChanged(CharSequence s){
if(!(s.length() < 1)){
passwordLayout.setError(null);
}
}
private void startSignIn(String email, String password){
firebaseAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(task -> {
try {
if (task.isSuccessful()) {
updateUI();
}
else {
String error = task.getException().getMessage();
if (error.contains("There is no user record corresponding to this identifier. The user may have been deleted.") ||
error.contains("The password is invalid or the user does not have a password."))
{
Utils.ErrorSweetDialog(LoginActivity.this, "Login Failed", "Incorrect email or pasword. Please try again.",
"OK");
}
else if (error.contains("A network error (such as timeout, interrupted connection or unreachable host) has occurred.")){
Utils.ErrorSweetDialog(LoginActivity.this, "No Internet Connection",
"Please check your internet connection and try again.", "OK");
}
else
{
Utils.ErrorSweetDialog(LoginActivity.this, "Login Failed", error, "OK");
}
}
progressBar.setVisibility(View.INVISIBLE);
}
catch (Exception e){
Utils.ErrorSweetDialog(LoginActivity.this, "Oops! Something went wrong.",
"Sorry for the inconvenience. Please try again later.", "OK");
}
});
}
@Override
protected void onStart() {
super.onStart();
//clearUserType();
//FirebaseUser user = firebaseAuth.getCurrentUser();
/*DocumentReference docRef = db.collection("UserInfo").document(uid); //ZJkUy7J5UzTok7ioADAYqk77Opp1
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()){
DocumentSnapshot document = task.getResult();
if(document.exists()){
String userType = document.getString("userType");
Log.e("LoginActivity",userType);
}
}
else{
}
}
});*/
/*if(user != null){
//updateUI();
String uid = firebaseAuth.getCurrentUser().getUid();
DocumentReference docRef = db.collection("UserInfo").document(uid); //ZJkUy7J5UzTok7ioADAYqk77Opp1
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()){
DocumentSnapshot document = task.getResult();
if(document.exists()){
String userType = document.getString("userType");
Log.e("LoginActivity",userType);
if (userType.contains("parents")){
Log.e("contain parents", "yes");
Intent intent = new Intent(getApplicationContext(), ParentActivity.class);
startActivity(intent);
finish();
}
else{
}
}
}
else{
}
}
});
Intent intent = new Intent(this, ParentActivity.class);
startActivity(intent);
finish();
}
else{
Log.e("Login", "hi");
}*/
}
private void updateUI(){
Intent intent = new Intent(this, PickRoleActivity.class);
startActivity(intent);
finish();
}
private void clearUserType(){
FirebaseUser user = firebaseAuth.getCurrentUser();
//Log.e("urrent user", user.toString());
if(user != null){
progressBar.setVisibility(View.VISIBLE);
Log.e("user null: ", "no");
//updateUI();
String uid = firebaseAuth.getCurrentUser().getUid();
Log.e("UID: ",uid);
DocumentReference docRef = db.collection("UserInfo").document(uid); //ZJkUy7J5UzTok7ioADAYqk77Opp1
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()){
DocumentSnapshot document = task.getResult();
if(document.exists()){
String userType = document.getString("userType");
String childStatus = document.getString("child");
Log.e("LoginActivity",userType);
if (userType.contains("parents")){
Log.e("contain parents", "yes");
progressBar.setVisibility(View.INVISIBLE);
Intent intent = new Intent(getApplicationContext(), ParentActivity.class);
startActivity(intent);
finish();
}
else if (childStatus.contains("TRUE")){
progressBar.setVisibility(View.INVISIBLE);
}
}
}
else{
Log.e("task unsuccessful:", " yes");
}
}
});
}
else{
Log.e("NULL: ", "No Such User.");
}
}
}
Комментарии:
1. при выходе пользователя из системы вы удалили значение
userType
?2. @Ticherhaz да, я сделал
3. итак, при повторной проверке входа пользователя в систему, при каждом входе пользователя в систему, проверяйте еще раз
4. да, каждый раз будет проверять, равен ли тип пользователя «родителям», если да, только автоматический вход, иначе загрузите страницу входа. Это для автоматического входа в систему родителей. Но, ребенок, я понятия не имею, как это сделать
5. можете ли вы опубликовать свои коды вместо скриншота.
Ответ №1:
Я предполагаю, что вы разрешаете создание нескольких учетных записей с одним и тем же адресом электронной почты, что означает, что у родителя и дочернего устройства разные пароли. При этом я предлагаю вам взглянуть на пользовательские утверждения. По сути, это дает учетной записи «тег», к которому вы можете получить доступ на стороне клиента. Пожалуйста, обратите внимание, что для этого вам потребуется написать некоторые облачные функции при создании учетных записей
РЕДАКТИРОВАТЬ: Кажется, что вам нужны SharedPreferences. Вот документы: developer.android.com/training/data-storage/shared-preferences . Таким образом, вы можете сохранить ключ, подобный isParent:true
, в SharedPreferences и считывать его значение при каждом запуске приложения вместо сохранения его в Firestore.
Комментарии:
1. Спасибо за ваш ответ. Однако я не включаю эту функцию. Дочернему устройству не нужно создавать учетную запись. Он / она просто использует родительский пароль электронной почты для входа. Затем система спросит, кто использует это устройство, родительское или дочернее. если родительский щелчок переходит к родительской активности, дочерний переходит к дочерней активности.
2. @SYL тогда как насчет локальной переменной? Поскольку вам это нужно только для отображения 1 из 2 пользовательских интерфейсов, я не думаю, что нужно идти в Firestore. Просто сохраните локальную переменную, нет?
3. Но как это может обеспечить автоматический вход в систему? Потому что теперь, что я делаю, это в onCreate метод LoginActivity, я проверяю, находятся ли пользовательские данные внутри кэша, используя FirebaseAuth.getCurrentUser(), если да, то он сразу загрузит основное действие вместо входа в систему. Как это сделать, используя только локальную переменную? Я буду признателен, если вы могли бы подробнее рассказать. Спасибо
4. Вы можете сохранить его в SharedPreferences. Вот документы: developer.android.com/training/data-storage/shared-preferences .
5. БОЖЕ!! Я наконец сделал это, это сработало! Я боролся за эту логическую проблему примерно 1-2 дня, не ожидал, что решение будет таким простым. Еще раз благодарю вас за вашего пациента, а также спасибо, что представили мне новый термин. Действительно ЦЕНЮ это!
Ответ №2:
Вы можете проверить их на onCreate
активность при входе в систему или, если у вас есть активность Splash, вы можете проверить там.
DocumentReference docRef = db.collection("UserInfo").document(uid); //ZJkUy7J5UzTok7ioADAYqk77Opp1
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()){
DocumentSnapshot document = task.getResult();
if(document.exists()){
String userType = document.getString("userType");
Log.e("LoginActivity",userType);
if (userType.equal("parents")){
Log.e("contain parents", "yes");
Intent intent = new Intent(getApplicationContext(), ParentActivity.class);
startActivity(intent);
finish();
}
else if (userType.equal("child")) {
//Here you missed, when child login
}
}
}
}
});
Комментарии:
1. Я думаю, возможно, есть какое-то недоразумение. На данный момент я делаю этот способ проверки родительского, но тип пользователя электронной почты может быть родительским или дочерним, если, скажем, устройство для входа в систему с помощью a@a.com и выберите вход в систему как родительский, тогда значением UserType будет «родители». Тогда у этого устройства не будет проблем с автоматическим входом в систему. Но если другое устройство B также входит в систему, используя тот же пароль электронной почты и логин как дочерний. Затем тип пользователя изменится на «дочерний». Теперь, когда устройство A открывает приложение, система загружает дочернюю активность вместо родительской. Я надеюсь, вы понимаете, что я имею в виду, я xD
2. Я вижу, как прокомментировал ThienLD, вы можете сохранить его в SharedPreferences.