From e04af237667d212eedda882bc5b4a1f7fa630078 Mon Sep 17 00:00:00 2001 From: "hermes@bounty.hunter" Date: Fri, 15 May 2026 00:20:24 +0700 Subject: [PATCH 1/2] fix: resolve bounty issue #5 - handle FirebaseAuthUserCollisionException properly When email linking fails with FirebaseAuthUserCollisionException, the user was left with a phone-only account that cannot login with email/password. Fix: sign out the orphaned phone-only account and redirect to login screen with the email pre-filled, so the user can login with the existing account. --- .../example/updateapp/views/activites/LoginActivity.java | 7 +++++++ .../example/updateapp/views/activites/OTPActivity.java | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java b/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java index 8700ad9..f872e4a 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/LoginActivity.java @@ -55,6 +55,13 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(binding.getRoot()); auth = FirebaseAuth.getInstance(); + + // Handle prefilled email from OTPActivity redirect + String prefilledEmail = getIntent().getStringExtra("prefilled_email"); + if (prefilledEmail != null && !prefilledEmail.isEmpty()) { + binding.edtEmail.setText(prefilledEmail); + } + googleBtn = findViewById(R.id.google_btn); emailBtn = findViewById(R.id.email_btn); diff --git a/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java b/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java index 918ed05..982c157 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java @@ -186,9 +186,16 @@ private void verifyCredential(PhoneAuthCredential credential) { String msg = e != null ? e.getMessage() : "Unknown linking error"; if (e instanceof FirebaseAuthUserCollisionException) { + // Email already exists with different account. + // Sign out this phone-only account and redirect to login with existing email. + auth.signOut(); Toast.makeText(OTPActivity.this, - "This email is already registered with a different account. Please login with that email or use another email.", + "An account with this email already exists. Please login with your email and password.", Toast.LENGTH_LONG).show(); + Intent intent = new Intent(OTPActivity.this, LoginActivity.class); + intent.putExtra("prefilled_email", email); + startActivity(intent); + finish(); } else { Toast.makeText(OTPActivity.this, "Failed to link email: " + msg, From d0f712600b3a4d89e9418b309251ce68f03bef3d Mon Sep 17 00:00:00 2001 From: "hermes@bounty.hunter" Date: Tue, 19 May 2026 16:37:06 +0700 Subject: [PATCH 2/2] fix: resolve bounty issue #5 - save user data before sign out on email collision When a user signs up with phone+email and the email already exists in Firebase Auth (FirebaseAuthUserCollisionException), the original code would: 1. Sign out the phone-only account immediately 2. Redirect to login with prefilled email The problem: user data (name, phone, etc.) was never saved to Firestore, so when the user logs in with the existing email account, their profile data is missing. Fix: Create a new saveUserToFirestoreOnCollision() method that: 1. Saves user data to Firestore FIRST (using the phone auth UID) 2. Then signs out the phone-only account 3. Then redirects to login with prefilled email This ensures the user's profile data is preserved even when the email linking fails due to an existing account. --- .../views/activites/OTPActivity.java | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java b/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java index 982c157..7cf80d6 100644 --- a/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java +++ b/app/src/main/java/com/example/updateapp/views/activites/OTPActivity.java @@ -187,15 +187,8 @@ private void verifyCredential(PhoneAuthCredential credential) { if (e instanceof FirebaseAuthUserCollisionException) { // Email already exists with different account. - // Sign out this phone-only account and redirect to login with existing email. - auth.signOut(); - Toast.makeText(OTPActivity.this, - "An account with this email already exists. Please login with your email and password.", - Toast.LENGTH_LONG).show(); - Intent intent = new Intent(OTPActivity.this, LoginActivity.class); - intent.putExtra("prefilled_email", email); - startActivity(intent); - finish(); + // Save phone-based user data to Firestore first, then redirect to login. + saveUserToFirestoreOnCollision(uid, name, email, number, password); } else { Toast.makeText(OTPActivity.this, "Failed to link email: " + msg, @@ -206,6 +199,49 @@ private void verifyCredential(PhoneAuthCredential credential) { }); } + private void saveUserToFirestoreOnCollision(String uid, String name, String email, String number, String password) { + if (name == null) name = ""; + if (email == null) email = ""; + if (number == null) number = ""; + if (password == null) password = ""; + + UserModel user = new UserModel( + name, + email, + number, + password, + "https://firebasestorage.googleapis.com/v0/b/earning-b8942.firebasestorage.app/o/account.png?alt=media&token=***" + ); + + if (dialog.isShowing()) dialog.dismiss(); + + firestore.collection("users") + .document(uid) + .set(user) + .addOnSuccessListener(unused -> { + // User data saved successfully. Now sign out and redirect to login. + auth.signOut(); + Toast.makeText(OTPActivity.this, + "An account with this email already exists. Please login with your email and password.", + Toast.LENGTH_LONG).show(); + Intent intent = new Intent(OTPActivity.this, LoginActivity.class); + intent.putExtra("prefilled_email", email); + startActivity(intent); + finish(); + }) + .addOnFailureListener(e -> { + // Failed to save - still redirect to login with email prefilled. + auth.signOut(); + Toast.makeText(OTPActivity.this, + "Failed to link email: " + e.getMessage() + ". Please login with your existing account.", + Toast.LENGTH_LONG).show(); + Intent intent = new Intent(OTPActivity.this, LoginActivity.class); + intent.putExtra("prefilled_email", email); + startActivity(intent); + finish(); + }); + } + private void saveUserToFirestoreAndContinue(String uid, String name, String email, String number, String password) { if (name == null) name = "";