身份验证和实时数据库同时进行?
Posted
技术标签:
【中文标题】身份验证和实时数据库同时进行?【英文标题】:Authentication and Realtime Database at the same time? 【发布时间】:2021-09-27 14:50:21 【问题描述】:我目前正在开发一个移动应用程序,作为我课程的最后一个项目。我使用 Firebase 作为应用程序的数据库。我在我们的应用中使用身份验证作为登录活动的工具。
现在,我在我的应用程序中使用实时数据库作为另一个工具来保存和检索数据。不幸的是,数据库没有保存我在注册活动中输入的数据,但我可以登录应用程序。我的问题是身份验证和实时数据库有可能在我的应用程序中同时工作吗?
这是我的代码。
登录活动:
public class Bio_LogIn extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
getSupportActionBar().hide(); // hides the action bar.
setContentView(R.layout.activity_bio_log_in);
//Firebase class, texbox/es and button/s declaration
FirebaseAuth FbaseAuth_LI = FirebaseAuth.getInstance();
TextInputEditText txtbx_Username = findViewById(R.id.txtbx_Username);
TextInputEditText txtbx_Password = findViewById(R.id.txtbx_SU_ConfirmPass);
Button btn_Log_In = findViewById(R.id.btn_Log_In);
Button btn_Forget_Pass = findViewById(R.id.btn_Forget_Pass);
Button btn_Sign_Up = findViewById(R.id.btn_Sign_Up);
AlertDialog.Builder alert_forget_pass = new AlertDialog.Builder(this);
LayoutInflater inflater_alert = this.getLayoutInflater();
btn_Log_In.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// data extraction and validation
if(txtbx_Username.getText().toString().isEmpty()) // gives error message when no username or email address input
txtbx_Username.setError("Email Address is missing."); // error message
return;
if(txtbx_Password.getText().toString().isEmpty()) // gives error message when no password input
txtbx_Password.setError("Password is missing."); // error message
return;
// successful account login
FbaseAuth_LI.signInWithEmailAndPassword(txtbx_Username.getText().toString(),txtbx_Password.getText().toString()).addOnSuccessListener(new OnSuccessListener<AuthResult>()
@Override
public void onSuccess(AuthResult authResult)
startActivity(new Intent(getApplicationContext(), MM_Play.class));
finish();
).addOnFailureListener(new OnFailureListener() //
@Override
public void onFailure(@NonNull Exception e)
Toast.makeText(Bio_LogIn.this, e.getMessage(), Toast.LENGTH_LONG).show();
);
);
btn_Forget_Pass.setOnClickListener(new View.OnClickListener()
// When "Forget Password" is clicked, an alert dialog will appear.
@Override
public void onClick(View v)
View view = inflater_alert.inflate(R.layout.alert_forget_pass, null);
alert_forget_pass.setTitle("Forget Password ?")
.setMessage("Enter your Email Address to get a Password Reset link.")
.setPositiveButton("Reset", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
TextInputEditText txtbx_FP_Email = view.findViewById(R.id.txtbx_FP_Email);
if(txtbx_FP_Email.getText().toString().isEmpty())
txtbx_FP_Email.setError("Required Field");
return;
FbaseAuth_LI.sendPasswordResetEmail(txtbx_FP_Email.getText().toString()).addOnSuccessListener(new OnSuccessListener<Void>()
@Override
public void onSuccess(Void aVoid)
Toast.makeText(Bio_LogIn.this, "Password Reset Link Sent", Toast.LENGTH_LONG).show();
).addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e)
Toast.makeText(Bio_LogIn.this, e.getMessage(), Toast.LENGTH_LONG).show();
);
).setNegativeButton("Cancel", null)
.setView(view)
.create().show();
);
btn_Sign_Up.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
startActivity(new Intent(Bio_LogIn.this, Bio_SignUp.class));;
);
// when the user already logged in in the app, they will go directly to the game.
@Override
protected void onStart()
super.onStart();
if(FirebaseAuth.getInstance().getCurrentUser() != null)
startActivity(new Intent(getApplicationContext(), MM_Play.class));
finish();
注册活动:
public class Bio_SignUp extends AppCompatActivity
EditText txtbx_SU_FullName, txtbx_SU_Email, txtbx_SU_Pass, txtbx_SU_ConfirmPass; // edit text declarations.
Button btn_Register; // button/s declaration/s.
ImageButton btn_SU_Back;
FirebaseAuth FbaseAuth_SU; //for authentication
FirebaseDatabase rootNode; // for realtime database
DatabaseReference reference;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
getSupportActionBar().hide(); // hides the action bar.
setContentView(R.layout.activity_bio_sign_up);
txtbx_SU_FullName = findViewById(R.id.txtbx_SU_FullName);
txtbx_SU_Email = findViewById(R.id.txtbx_SU_Email);
txtbx_SU_Pass = findViewById(R.id.txtbx_SU_Pass);
txtbx_SU_ConfirmPass = findViewById(R.id.txtbx_SU_ConfirmPass);
btn_Register = findViewById(R.id.btn_Register);
btn_SU_Back = findViewById(R.id.btn_SU_Back);
FbaseAuth_SU = FirebaseAuth.getInstance();
rootNode = FirebaseDatabase.getInstance();
reference = rootNode.getReference("users");
btn_Register.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
String fullname = txtbx_SU_FullName.getText().toString();
String email = txtbx_SU_Email.getText().toString();
String password = txtbx_SU_Pass.getText().toString();
String ConPassword = txtbx_SU_ConfirmPass.getText().toString();
UserHelper UHelper = new UserHelper(fullname, email, password);
if(fullname.isEmpty() && email.isEmpty() && password.isEmpty()) // condition if full name field is empty,
txtbx_SU_FullName.setError("This field cannot be empty."); // this error message will be shown.
return;
if (!ConPassword.equals(password)) // condition if the confirm password is not equals to password,
txtbx_SU_ConfirmPass.setError("Password does not match."); // this error message will be shown.
return;
reference.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
reference.child(fullname).setValue(UHelper);
@Override
public void onCancelled(@NonNull DatabaseError error)
Toast.makeText(getApplicationContext(),error.getMessage(), Toast.LENGTH_LONG).show();
);
Toast.makeText(Bio_SignUp.this, "Data Validated", Toast.LENGTH_LONG).show(); // notification that data is validated.
FbaseAuth_SU.createUserWithEmailAndPassword(email, password).addOnSuccessListener(new OnSuccessListener<AuthResult>()
@Override
public void onSuccess(AuthResult authResult) // send the user to the log - in screen.
startActivity(new Intent(getApplicationContext(), Bio_LogIn.class));
finish();
).addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e) // an error when email and pass is wrong or invalid.
Toast.makeText(Bio_SignUp.this, e.getMessage(), Toast.LENGTH_LONG).show();
);
);
btn_SU_Back.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
finish();
);
【问题讨论】:
【参考方案1】:所以,首先,这一行
Toast.makeText(Bio_SignUp.this, "Data Validated", Toast.LENGTH_LONG).show();
即使将值设置为realtime database
失败以及createUserWithEmailAndPassword
失败时也会执行,因为它位于onSuccess
块之外,因此目前Toast
消息Data Validated
没有说明任何内容。
其次,您不需要在此处使用ValueEventListener
将值设置为firebase
。它用于reading
值,在此代码中从未使用过DataSnapshot
。所以可以直接拨打.setValue(UHelper)
你想要做的是,在createUserWithEmailAndPassword
的Bio_SignUp
Activity 的onSuccess
方法中,调用这个setValue(uHelper)
。
FbaseAuth_SU.createUserWithEmailAndPassword(email, password).addOnSuccessListener(new OnSuccessListener<AuthResult>()
@Override
public void onSuccess(AuthResult authResult) // send the user to the log - in screen.
reference.setValue(uHelper).addOnSuccessListener(new OnSuccessListener
@Override
public void onSuccess()
Toast.makeText(Bio_SignUp.this, "Data Validated", Toast.LENGTH_LONG).show();
startActivity(new Intent(getApplicationContext(), Bio_LogIn.class));
finish();
).addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e) // an error when email and pass is wrong or invalid.
Toast.makeText(Bio_SignUp.this, e.getMessage(), Toast.LENGTH_LONG).show();
);
【讨论】:
【参考方案2】:身份验证和实时数据库是否可以在我的应用中同时工作?
是的,可以在同一个应用中使用 Firebase 身份验证和实时数据库。例如,您可以查看面向 android 开发人员的 Firebase 代码实验室here。
这意味着问题可能出在您的代码中,您需要对其进行调试以找出问题所在。我会在下面指出一些地方,但可能还有更多问题。
这看起来很不寻常:
reference.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
reference.child(fullname).setValue(UHelper);
@Override
public void onCancelled(@NonNull DatabaseError error)
Toast.makeText(getApplicationContext(),error.getMessage(), Toast.LENGTH_LONG).show();
);
由于您没有对onDataChange
中的数据进行任何操作,因此无需先阅读它。我建议用这一行替换上面的代码:
reference.child(fullname).setValue(UHelper);
我通常还会向add a completion listener 推荐此电话,以便您在其中出现问题时进行记录。
Firebase 客户端需要知道您的数据库 URL 才能在服务器上找到您的数据库。
此代码从您从 Firebase 控制台下载的 google-services.json
文件中读取该 URL:
rootNode = FirebaseDatabase.getInstance();
最近我们看到一些开发人员在在控制台中创建数据库之前下载 JSON 文件时访问数据库时遇到问题。
如果您遇到同样的问题,可以通过在代码中直接指定数据库 URL 来解决:
rootNode = FirebaseDatabase.getInstance("database URL here");
【讨论】:
以上是关于身份验证和实时数据库同时进行?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Firebase 身份验证服务并在我们自己的数据库中拥有用户?
如何在 Spring 安全性中同时使用数据库和 LDAP 身份验证?