I have a login page which when registering a new user authenticates the data if it is validated and then is meant to store them. However, after the data is authenticated it doesn't add to the real time database.
Register java code:
progressBar.setVisibility(View.VISIBLE);
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
User user = new User(fullname, email);
FirebaseDatabase.getInstance().getReference("Users")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
progressBar.setVisibility(View.GONE);
Toast.makeText(RegisterActivity.this, "User has registered successfully", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(RegisterActivity.this, "Failed to register", Toast.LENGTH_LONG).show();
}
progressBar.setVisibility(View.GONE);
}
});
}
else{
Toast.makeText(RegisterActivity.this, "Failed to register22", Toast.LENGTH_LONG).show();
progressBar.setVisibility(View.GONE);
}
}
});
}
}
Dependencies:
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.6.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'com.google.firebase:firebase-auth:21.0.4'
implementation 'com.google.firebase:firebase-database:20.0.5'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
I have set the rules of the database as below:
{
"rules": {
".read": true, // 2022-6-14
".write": true, // 2022-6-14
}
}
Finally my database also only shows this:
https://hobby-tracker-a914f-default-rtdb.europe-west1.firebasedatabase.app/
:
null
Does anyone have any clue why this is happening?
If neither of the toasts you have in the onComplete method are showing, then it may be that you downloaded the google-services.json file before you created your database. If that's the case, the file doesn't contain the database URL, and thus the client can't find your database on the server.
In that case, you can solve it by:
either download an updated google-services.json file, replacing the one in your project with it, and rebuilding the app.
or you can specify the URL for your database in the code, like this: FirebaseDatabase.getInstance("https://hobby-tracker-a914f-default-rtdb.europe-west1.firebasedatabase.app/").getReference("Users")...
Related
I am trying to be able to register users into my database.
After I register the users they are being added to my firebase authentication which is great but nothing is changed in my Realtime Database.
It's worth mentioning that my Firebase location isn't in the US.
I have tried many different things:
Put the firebase link inide of the "getInstance()"
Replace the current google-services file with an updated one, including the Firebase's link inside of it
use getReferenceFromUrl() with the firebase's link inside of it.
None of those seemed to work.
Main part of the code in which I'm trying to register the user:
mAuth.createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
User user = new User(name, email, password);
FirebaseDatabase.getInstance().getReference("Users")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(RegisterUser.this, "User Registered", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(RegisterUser.this, "Failed to register user", Toast.LENGTH_SHORT).show();
}
}
});
}else{
Toast.makeText(RegisterUser.this, "Failed to register user", Toast.LENGTH_SHORT).show();
}
}
});
These are the Realtime Database rules:
{
"rules": {
".read": "true",
".write": "true"
}
}
It's worth noting that I have tried everything I found, including an answer to the same question in this site. Unfortunately none seem to work for me so I had to ask to understand the issue.
Thanks.
I have the following in a login activity that gets triggered to sign in a user to my app:
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
...
LoggedInUser loggedInUser = LoggedInUser.getInstance();
Toast.makeText(LoginActivity.this, getString(R.string.welcome_back) + loggedInUser.getUser().name, Toast.LENGTH_LONG).show();
The sign in and the listener above are successfully triggered. However, I am having an issue occur on that Toast line where I call loggedInUser.getUser().name
public User getUser() {
if (user == null) {
FirebaseAuth mAuth = FirebaseAuth.getInstance();
String userID = mAuth.getCurrentUser().getUid();
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Users").child(userID);
databaseReference.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (!task.isSuccessful()) {
Log.e("firebase", "Error getting data", task.getException());
}
else {
User currUser = task.getResult().getValue(User.class);
user = currUser;
}
}
});
}
return user;
}
What happens here is that databaseReference.get().addOnCompleteListener never gets triggered so user is never set, it returns null and the app crashes.
I utilized the same code I have in getUser to set a user elsewhere with no issues so I am not sure what I am missing here that is causing the listener to be skipped. I am new to firebase so any help to understand and fix this is appreciated!
Not sure if I fully understand your code but you can get your user object from mAuth.getCurrentUser() inside signInWithEmailAndPassword.
Refer to the docs.
Also bear in mind that calls to the Firebase database are asynchronous. So this means in your getUser() method, you'll probably get a null return when you enter the if == null block i.e your addOnCompleteListener executes after your return user statement.
I want to check when a user attempts to signup with createUserWithEmailAndPassword() in Firebase user Authentication method, this user is already registered with my app.
To detect whether a user with that email address already exists, you can detect when the call to createUserWithEmailAndPassword () fails with auth/email-already-in-use. I see that #Srinivasan just posted an answer for this.
Alternatively, you can detect that an email address is already used by calling fetchSignInMethodsForEmail().
The usual flow for this is that you first ask the user to enter their email address, then call fetchSignInMethodsForEmail, and then move them to a screen that either asks for the rest of their registration details (if they're new), or show them the provider(s) with which they're signed up already.
When the user trying to create an user with same email address, the task response will be "Response: The email address is already in use by another account."
mFirebaseAuth.createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
//User registered successfully
}else{
Log.i("Response","Failed to create user:"+task.getException().getMessage());
}
}
});
First of all, you need to make sure you have that restriction enabled in Firebase console (Account and email address settings). Take a look at #Srinivasan's answer.
Then, do this in your java code:
firebaseAuthenticator.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
if (task.getException() instanceof FirebaseAuthUserCollisionException) {
Toast.makeText(SignUpActivity.this, "User with this email already exist.", Toast.LENGTH_SHORT).show();
}
} else {
sendVerificationEmail();
startActivity(new Intent(SignUpActivity.this, DetailsCaptureActivity.class));
}
// ...
}
});
This is where the trick happens:
if (task.getException() instanceof FirebaseAuthUserCollisionException) {
Toast.makeText(SignUpActivity.this,
"User with this email already exist.", Toast.LENGTH_SHORT).show();
Several exceptions can be thrown when registering a user with email and password, but the one we are interested in is the FirebaseAuthUserCollisionException. As the name implies, this exception is thrown if the email already exists. If the exception thrown is an instance of this class, let the user know.
As a practice of #Frank's answer here is the code of using fetchProvidersForEmail()
private boolean checkAccountEmailExistInFirebase(String email) {
FirebaseAuth mAuth = FirebaseAuth.getInstance();
final boolean[] b = new boolean[1];
mAuth.fetchProvidersForEmail(email).addOnCompleteListener(new OnCompleteListener<ProviderQueryResult>() {
#Override
public void onComplete(#NonNull Task<ProviderQueryResult> task) {
b[0] = !task.getResult().getProviders().isEmpty();
}
});
return b[0];
}
I was looking into this kind of condition where we can detect if user exists or not and perform registration and login. fetchProvidersForEmail is best option right now. I have found this tutorial. Hope it helps you too!
See : Manage Users
UserRecord userRecord = FirebaseAuth.getInstance().getUserByEmail(email);
System.out.println("Successfully fetched user data: " + userRecord.getEmail());
This method returns a UserRecord object for the user corresponding to the email provided.
If the provided email does not belong to an existing user or the user cannot be fetched for any other reason, the Admin SDK throws an error. For a full list of error codes, including descriptions and resolution steps, see Admin Authentication API Errors.
private ProgressDialog progressDialog;
progressDialog.setMessage("Registering, please Wait...");
progressDialog.show();
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
//checking if success
if (task.isSuccessful()) {
//Registration was successfull:
Toast.makeText(RegistrationActivity.this, "Successfully registered!", Toast.LENGTH_LONG).show();
} else {
//Registration failed:
//task.getException().getMessage() makes the magic
Toast.makeText(RegistrationActivity.this, "Registration failed! " + "\n" + task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
progressDialog.dismiss();
}
});
Add below code to MainActivity.java file.When user attempt to register with the same email address a message "The email address is already used by another account" will pop up as a Toast
mAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(!task.isSuccessful()){
Toast.makeText(MainActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
if(task.isSuccessful()){
Toast.makeText(MainActivity.this, "Sign up successfull", Toast.LENGTH_SHORT).show();
}
}
});
You do not have to do anything because the backend of Firebase will do the job.
Unless you are referring to reauthenticating of the app.
Take a scenario for an example, w
I am creating an android app that registers a user to firebase Authentication. So as you can see below this is the program i made to give you a hint on what i am referring . . .
public void createAccount(final String email, final String password, final String firstname, final String lastname)
{
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "createUserWithEmail:success");
FirebaseUser user = mAuth.getCurrentUser();
UserInformation UInfo = new UserInformation(user.getUid(), user.getEmail(), password, firstname, lastname);
newRef = database.getReference("Users");
newRef.child(user.getUid()).setValue(UInfo);
//newRef.child(user.getUid()).child("id").setValue(user.getUid());
Toast.makeText(Signup.this, "User registered: " + user.getEmail(), Toast.LENGTH_LONG).show();
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(Signup.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
}
});
}
after register succeeds all other devices also gets affected as well, in terms of, all the other devices prompts as if they've just logged in again.
my problem is, why does it do that? why does all other devices gets affected as if they've just logged in again. what's causing the issue?
also, this is my database rules.
{
"rules": {
".read": true,
".write": true
}
}
I'm trying to create an app that only uses phone authorization from firebase. Since the login/signup is done through same process, which is verifying the sent code. How can i check if a user already exists in firebase? I need this to show them appropriate User Interface.
Right now, the only way to do that is via the Firebase Admin SDK. There is an API to lookup a user by phone number.
admin.auth().getUserByPhoneNumber(phoneNumber)
.then(function(userRecord) {
// User found.
})
.catch(function(error) {
console.log("Error fetching user data:", error);
});
You can check whether user already exist in Firebase by compare it metadata. see code example:
PhoneAuthCredential phoneAuthCredential = PhoneAuthProvider.getCredential(verificationId, smsCode);
FirebaseAuth.getInstance().signInWithCredential(phoneAuthCredential).addOnCompleteListener(PhoneLoginEnterCodeActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task){
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
FirebaseUser user = task.getResult().getUser();
long creationTimestamp = user.getMetadata().getCreationTimestamp();
long lastSignInTimestamp = user.getMetadata().getLastSignInTimestamp();
if (creationTimestamp == lastSignInTimestamp) {
//do create new user
} else {
//user is exists, just do login
}
} else {
// Sign in failed, display a message and update the UI
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
}
}
}
});
There is an additionalUserInfo property that you can query like so (Kotlin):
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener {
it.result.additionalUserInfo?.isNewUser // new user check
}
If I borrow #Eltanan Derek code:
PhoneAuthCredential phoneAuthCredential = PhoneAuthProvider.getCredential(verificationId, smsCode);
FirebaseAuth.getInstance().signInWithCredential(phoneAuthCredential).addOnCompleteListener(PhoneLoginEnterCodeActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task){
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
FirebaseUser user = task.getResult().getUser().getAdditionalUserInfo();
if (user.isNewUser()) {
//do create new user
} else {
//user is exists, just do login
}
} else {
// Sign in failed, display a message and update the UI
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
}
}
}
});