Reputation: 55
I'm currently working on a mobile app as our final project in my course. I use Firebase as the database of the app. I use Authentication as a tool for Log-in Activity in our app.
Now, I use the Realtime Database as another tool in my app to save and retrieve data. Unfortunately, the database didn't save the data I inputted in my Sign-Up Activity, but I can log into the app. My question is it possible that Authentication and Realtime Database works at the same time in my app?
Here is my code.
LOGIN ACTIVITY:
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();
}
}
}
SIGN-UP ACTIVITY:
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();
}
});
}
}
Upvotes: 1
Views: 980
Reputation: 742
So, first of all, this line
Toast.makeText(Bio_SignUp.this, "Data Validated", Toast.LENGTH_LONG).show();
It would be executed even when setting the value to realtime database
failed and also when createUserWithEmailAndPassword
fails because it is placed outside the onSuccess
block so currently that Toast
message Data Validated
doesn't tell anything.
Secondly, you don't need a ValueEventListener
here to set the value to firebase
. It is used for reading
values, and in this code the DataSnapshot
is never used. So you can directly call .setValue(UHelper)
What you would want to do here is, inside the onSuccess
method of the createUserWithEmailAndPassword
inside Bio_SignUp
Activity, call this 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();
}
});
Upvotes: 2
Reputation: 600006
is it possible that Authentication and Realtime Database works at the same time in my app?
Yes, it is possible to use Firebase Authentication and Realtime Database in the same app. For an example of this, you can have a look at the Firebase codelab for Android developers here.
So that means the problem is likely somewhere in your code, and you'll need to debug it to find out what's going wrong. I'll point out some areas below, but there may be more problems.
This looks really unusual:
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();
}
});
Since you're not doing anything with the data in onDataChange
, there is no need to read it first. I recommend replacing the above code with this single line:
reference.child(fullname).setValue(UHelper);
I'd typically also recommend to add a completion listener to this call, so that you can log if something goes wrong in it.
The Firebase client needs to know your database URL to find your database on the server.
This code reads that URL from the google-services.json
file that you download from the Firebase console:
rootNode = FirebaseDatabase.getInstance();
Recently we've seen some developers having problems accessing the database when they downloaded the JSON file before they created the database in the console.
If you're experiencing this same problem, you can solve it by specifying the database URL in the code directly with:
rootNode = FirebaseDatabase.getInstance("database URL here");
Upvotes: 2