I used firebase phone and google authentication in my app I am facing an issue that when a user logout and signing again though OTP or google it signup the user again by creating new user id and all the information that user update through profile update option erased and come back in original state as new user and all updates of profile lost.
My phone sign in code is here
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(auth)
.setPhoneNumber(phoneNumber)
.setTimeout(120L, TimeUnit.SECONDS)
.setActivity(this)
.setCallbacks(new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
}
#Override
public void onCodeSent(#NonNull String verifyId, #NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(verifyId, forceResendingToken);
verificationId = verifyId;
}
}).build();
PhoneAuthProvider.verifyPhoneNumber(options);
}
public void callNextScreen(View view) {
dialog.show();
String otp = binding.otpView.getText().toString();
if (otp!= null) {
verifyOTP(otp);
} else {
Toast.makeText(this, "Enter code", Toast.LENGTH_LONG).show();
}
}
private void verifyOTP(String otp) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, otp);
auth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
String uid = auth.getCurrentUser().getUid();
String phoneNumber = auth.getCurrentUser().getPhoneNumber();
User users = new User();
users.setPhone(phoneNumber);
database
.collection("users")
.document(uid)
.set(users).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
dialog.dismiss();
Intent intent = new Intent(OTP_Activity.this, MainActivity.class);
startActivity(intent);
finishAffinity();
} else {
dialog.dismiss();
Toast.makeText(OTP_Activity.this, task.getException().getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
}
});
} else {
dialog.dismiss();
Toast.makeText(OTP_Activity.this, task.getException().getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
and my user attributes and user class constructor looks like this
private String name, email, image, phone, gender;
private long coins = 500;
public User(String name, String email, String image, String phone, String gender) {
this.name = name;
this.email = email;
this.image = image;
this.phone = phone;
this.gender = gender;
}
public User() {
}
this is how creating user profile with google signing
private void firebaseAuthWithGoogle(String idToken){
AuthCredential firebaseCredential = GoogleAuthProvider.getCredential(idToken, null);
auth.signInWithCredential(firebaseCredential)
.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", "signInWithCredential:success");
FirebaseUser user = auth.getCurrentUser();
String uid = user.getUid();
User newUser = new User();
newUser.setName(user.getDisplayName());
newUser.setEmail(user.getEmail());
newUser.setImage(user.getPhotoUrl().toString());
database
.collection("users")
.document(uid)
.set(newUser).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
dialog.dismiss();
Intent intent = new Intent(SignupActivity.this, MainActivity.class);
startActivity(intent);
finishAffinity();
} else {
dialog.dismiss();
Log.w("TAG", "signInWithCredential:failure", task.getException());
Toast.makeText(SignupActivity.this, task.getException().getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
}
});
} else {
dialog.dismiss();
// If sign in fails, display a message to the user.
Toast.makeText(SignupActivity.this, "Signup Failed", Toast.LENGTH_SHORT).show();
// updateUI(null);
}
}
});
}
Related
I am working on a kind of shopping Android app and at the time of creating new user account i want to verify the user with his Phone number and want to log in the user by there email.
PhoneAuthProvider.getInstance().verifyPhoneNumber(users.getPhoneNumber(), 120, TimeUnit.SECONDS, Otp_Activity.this,
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onCodeSent(#NonNull #NotNull String s, #NonNull #NotNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
otpID = s;
progressDialog.dismiss();
Toast.makeText(Otp_Activity.this, "Otp sent", Toast.LENGTH_SHORT).show();
}
#Override
public void onVerificationCompleted(#NonNull #NotNull PhoneAuthCredential phoneAuthCredential) {
signInWithPhoneAuthCredential(phoneAuthCredential);
}
#Override
public void onVerificationFailed(#NonNull #NotNull FirebaseException e) {
Toast.makeText(Otp_Activity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
});
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
firebaseAuth = SplashScreen.firebaseAuthForPhone;
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful())
{
Toast.makeText(Otp_Activity.this, "Account Created", Toast.LENGTH_SHORT).show();
createAccountWithEmail(userEmail, userPassword);
}
else
{
Toast.makeText(Otp_Activity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
public void createAccountWithEmail(String email, String passWord)
{
firebaseAuthForEmail.createUserWithEmailAndPassword(email, passWord)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
firebaseAuth.signOut();
Toast.makeText(Otp_Activity.this, "Email Account Created", Toast.LENGTH_SHORT).show();
startActivity(new Intent(getApplicationContext(), MainActivity.class));
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull #NotNull Exception e) {
Toast.makeText(Otp_Activity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
Why i cant logout with the account created with email?
do PhoneAuthProvider logs in after verifying account? if yes is there any way to stop it?
You could use one specific authentication process for each user. If you need to authenticate the user with the email and password, follow this process.
private FirebaseAuth mAuth;
// Initialize Firebase Auth
mAuth = FirebaseAuth.getInstance();
Then create account with email and password.
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// add the logic
} else {
// add the logic
}
}
});
After account creating process, you could use this process for the sign in process.
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// add the logic
} else {
// add the logic
}
}
});
And you could use this method for sign out the user.
FirebaseAuth.getInstance().signOut();
I am working on my project and I need save information about my users. I chose Realtime Database, but it doesnt work. I have an exception:
This email is already in use
through I insert new email. I use everything(google.json, SHA-1, SHA-256), but my signing up new users doesnt work correctly. My rules:
{
"rules": {
".read": true,
".write": true
}
}
My class Person:
public String name, email;
public User(){}
public User(String name, String email){
this.name = name;
this.email = email;
}
}
My FireBaseAuth, FireBaseDataBase:
private FirebaseAuth mAuth;
private FirebaseDatabase usersDataBase;
///
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
User user = new User(username, email);
FirebaseDatabase.getInstance().getReference("Users")
.child(FirebaseAuth.getInstance().getUid())
.setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(RegisterActivity.this, "Пользователь успешно добавлен", Toast.LENGTH_SHORT).show();
startActivity(new Intent(RegisterActivity.this, SigningActivity.class));
}
else{
Toast.makeText(RegisterActivity.this, "Произошла ошибка! Пожалуйста, попробуйте позже", Toast.LENGTH_SHORT).show();
}
}
});
}
else {
Toast.makeText(RegisterActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
I've a project using firebase phoneAuth verification as login method. But after logout, I can't re-login to previous account. It requires new account. But email verification works with re-login. I've check the doc and answer from this page but it seem l haven't got solution to the problem. Is it possible to re-login to previous account firebase phoneAuth ?
verifyBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String phoneNumber = loginPhoneET.getText().toString();
String phone = "+" + picker.getSelectedCountryCode() + phoneNumber;
if(!Patterns.PHONE.matcher(phoneNumber).matches())
{
loginPhoneET.setError("Invalid phone number");
loginPhoneET.setFocusable(true);
Toast.makeText(LoginActivity.this, "Please enter a valid phone number", Toast.LENGTH_LONG).show();
}
else
{
loadingBar.setTitle("Sending verification code");
loadingBar.setMessage("Please wait...");
loadingBar.setCanceledOnTouchOutside(false);
loadingBar.show();
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phone, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
TaskExecutors.MAIN_THREAD,
//AdminLoginActivity.this, // Activity (for callback binding)
callbacks); // OnVerificationStateChangedCallbacks
}
}
});
loginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loginPhoneET.setVisibility(View.INVISIBLE);
verifyBtn.setVisibility(View.INVISIBLE);
String verificationCode = verificationET.getText().toString();
if(TextUtils.isEmpty(verificationCode))
{
Toast.makeText(LoginActivity.this, "Please enter the verification code", Toast.LENGTH_SHORT).show();
}
else
{
loadingBar.setTitle("Verifying code");
loadingBar.setMessage("Please wait...");
loadingBar.setCanceledOnTouchOutside(false);
loadingBar.show();
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, verificationCode);
signInWithPhoneAuthCredential(credential);
}
}
});
callbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential)
{
String code = phoneAuthCredential.getSmsCode();
if (code!=null)
{
verificationET.setText(code);
signInWithPhoneAuthCredential(phoneAuthCredential);
}
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e)
{
loadingBar.dismiss();
Toast.makeText(LoginActivity.this, "Invalid phone number. Please enter a correct phone number", Toast.LENGTH_SHORT).show();
verificationET.setVisibility(View.GONE);
loginBtn.setVisibility(View.GONE);
loginPhoneET.setVisibility(View.VISIBLE);
verifyBtn.setVisibility(View.VISIBLE);
}
#Override
public void onCodeSent(#NonNull String verificationId,
#NonNull PhoneAuthProvider.ForceResendingToken token) {
// Save verification ID and resending token so we can use them later
mVerificationId = verificationId;
mResendToken = token;
loadingBar.dismiss();
Toast.makeText(LoginActivity.this, "Verification code has been sent to your phone.", Toast.LENGTH_SHORT).show();
verificationET.setVisibility(View.VISIBLE);
loginBtn.setVisibility(View.VISIBLE);
loginPhoneET.setVisibility(View.GONE);
verifyBtn.setVisibility(View.GONE);
}
};
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task)
{
if (task.isSuccessful()) {
final FirebaseUser user = mAuth.getCurrentUser();
final String uid = user.getUid();
final String phone = user.getPhoneNumber();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("userId", uid);
hashMap.put("phone", phone);
UsersDataRef.child(uid).setValue(hashMap).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
loadingBar.dismiss();
Toast.makeText(LoginActivity.this, "Login success !", Toast.LENGTH_SHORT).show();
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
SendUserToPhotoActivity(phone, uid);
}
});
} else {
String message = task.getException().toString();
Toast.makeText(LoginActivity.this, "Error:" + message, Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
}
});
Firebase register code is given below. When I add username as a parameter, the method does not let me do it.
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
//checking if success
if(task.isSuccessful()){
finish();
startActivity(new Intent(getApplicationContext(), MainActivity.class));
}else{
//display some message here
Toast.makeText(RegisterActivity.this,"Bir hata oldu",Toast.LENGTH_LONG).show();
}
progressDialog.dismiss();
}
});
you need to update user after creating it.
firebaseAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
Toast.makeText(YourActivity.this, "An error occurred", Toast.LENGTH_SHORT).show();
} else {
addUserNameToUser(task.getResult().getUser());
}
}
)};
private void addUserNameToUser(User user){
String username = "username";
String email = user.getEmail();
String userId = user.getUid();
User user = new User(username, email);
firebaseDB.child("users").child(userId).setValue(user);
}
the variable firebaseDB should be created before. You can create in where you create firebaseAuth like so ;
firebaseDB = FirebaseDatabase.getInstance().getReference();
Update 1
using com.google.firebase:firebase-auth:11.6.2
public class MainActivity extends AppCompatActivity {
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
firebaseAuth.createUserWithEmailAndPassword("erginersoyy#gmail.com", "12345").addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
Toast.makeText(MainActivity.this, "An error occurred", Toast.LENGTH_SHORT).show();
} else {
addUserNameToUser(task.getResult().getUser());
}
}
});
}
private void addUserNameToUser(FirebaseUser user) {
String username = "username";
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(username)
.setPhotoUri(Uri.parse("https://example.com/jane-q-user/profile.jpg"))
.build();
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User profile updated.");
}
}
});
}
}
you can also check this link
It seems I can only find a way to update the display name of a current user, although I would like to do it while registering.
Here is the code I have been trying but it is not working, i have read about a bug in firebase that requires signing out for the display name to show but this hasnt solved my problem. Here is the code
public void btnRegistrationUser_Click(View v) {
final String email = txtEmailAddress.getText().toString();
final String password = txtPassword.getText().toString();
final String username = txtUsername.getText().toString();
final ProgressDialog progressDialog = ProgressDialog.show(RegistrationActivity.this, "Please wait...", "Processing...", true);
(firebaseAuth.createUserWithEmailAndPassword(email,password ))
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
progressDialog.dismiss();
if (task.isSuccessful()) {
//Sign in the user here
signin(email,password,username);
}
else
{
Log.e("ERROR", task.getException().toString());
Toast.makeText(RegistrationActivity.this, task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
}
});
}
private void signin(String email, String password, final String username) {
firebaseAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
//New Account is signed in and now the Current User
FirebaseUser user = firebaseAuth.getInstance().getCurrentUser();
Toast.makeText(RegistrationActivity.this, "curr user is "+user.getEmail(), Toast.LENGTH_LONG).show();
Toast.makeText(RegistrationActivity.this, "passed in username is "+username, Toast.LENGTH_LONG).show();
firebaseAuth.getInstance().signOut();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(username)
.build();
// Toast.makeText(RegistrationActivity.this, "Registration successful", Toast.LENGTH_LONG).show();
Toast.makeText(RegistrationActivity.this, "curr display name is "+user.getDisplayName(), Toast.LENGTH_LONG).show();
Intent i = new Intent(RegistrationActivity.this, LoginActivity.class);
startActivity(i);
}
}
});
}
}
Thanks
Maybe you could try to login the user since the account registration is successful. That way the current user would be the currently registered one.
public void btnRegistrationUser_Click(View v) {
final String email = txtEmailAddress.getText().toString();
final String password = txtPassword.getText().toString();
final String username = txtUsername.getText().toString();
final ProgressDialog progressDialog = ProgressDialog.show(RegistrationActivity.this, "Please wait...", "Processing...", true);
(firebaseAuth.createUserWithEmailAndPassword(email,password ))
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
progressDialog.dismiss();
if (task.isSuccessful()) {
//Sign in the user here
signin(email,password,username);
}
else
{
Log.e("ERROR", task.getException().toString());
Toast.makeText(RegistrationActivity.this, task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
}
});
}
private void signin(String email, String password, final String username) {
firebaseAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
//New Account is signed in and now the Current User
FirebaseUser user = firebaseAuth.getInstance().getCurrentUser();
Toast.makeText(RegistrationActivity.this, "curr user is "+user.getEmail(), Toast.LENGTH_LONG).show();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(username)
.build();
user.updateProfile(profileUpdates)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(RegistrationActivity.this, "curr display name is "+user.getDisplayName(), Toast.LENGTH_LONG).show();
}
}
});
Intent i = new Intent(RegistrationActivity.this, LoginActivity.class);
startActivity(i);
}
}
});
You also forgot the user by calling the updateProfile() method.
Check this out for more info: https://firebase.google.com/docs/auth/android/manage-users