I’m new to Android Studio and coding in general. I was tasked to develop a school group project. I was coding the sign-up page for the app and this issue suddenly popped up. It was working before when I haven’t configured the PhoneVerificationActivity to handle different intent sources. Firebase Auth sends the OTP but verifying it doesn’t seem to work now but the app does insert the user details in the Realtime Database and creates a folder in the Firebase Storage when I removed the OTP function for troubleshooting. I don’t know if it’s the IDE, Firebase setup, or my code.
Here are the source codes:
package com.example.best_csportal;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
public class RegistrationActivity extends AppCompatActivity {
private static final int PHONE_VERIFICATION_REQUEST = 101;
private EditText usernameEditText;
private EditText phoneNumberEditText;
private EditText passwordEditText;
private EditText confirmPasswordEditText;
private Button registerButton;
private Button loginButton;
private DatabaseReference databaseReference;
private FirebaseAuth auth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_registration);
// Initialize Firebase Auth
auth = FirebaseAuth.getInstance();
FirebaseDatabase database = FirebaseDatabase.getInstance("https://best-cs-default-rtdb.asia-southeast1.firebasedatabase.app");
databaseReference = database.getReference("users");
usernameEditText = findViewById(R.id.etext_rusername);
phoneNumberEditText = findViewById(R.id.etext_rphone);
passwordEditText = findViewById(R.id.etext_rpassword);
confirmPasswordEditText = findViewById(R.id.etext_rcpassword);
registerButton = findViewById(R.id.button_rregister);
loginButton = findViewById(R.id.button_rlogin);
registerButton.setOnClickListener(v -> initiatePhoneVerification());
loginButton.setOnClickListener(v -> startActivity(new Intent(this, LoginActivity.class)));
}
private void initiatePhoneVerification() {
String phoneNumber = phoneNumberEditText.getText().toString();
Intent intent = new Intent(this, PhoneVerificationActivity.class);
intent.putExtra("phoneNumber", phoneNumber);
startActivityForResult(intent, PHONE_VERIFICATION_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PHONE_VERIFICATION_REQUEST && resultCode == RESULT_OK) {
registerUser();
} else {
Toast.makeText(this, "OTP verification failed. Please try again.", Toast.LENGTH_LONG).show();
}
}
private void registerUser() {
String username = usernameEditText.getText().toString().trim();
String rawPhoneNumber = phoneNumberEditText.getText().toString().trim();
String password = passwordEditText.getText().toString().trim();
String confirmPassword = confirmPasswordEditText.getText().toString().trim();
// Process the phone number for the desired format
final String phoneNumber;
if (rawPhoneNumber.startsWith("0")) {
phoneNumber = rawPhoneNumber.replaceFirst("0", "+63");
} else if (!rawPhoneNumber.startsWith("+63")) {
phoneNumber = "+63" + rawPhoneNumber;
} else {
phoneNumber = rawPhoneNumber;
}
if (username.isEmpty() || phoneNumber.isEmpty() || password.isEmpty() || confirmPassword.isEmpty()) {
Toast.makeText(this, "All fields must be filled", Toast.LENGTH_SHORT).show();
return;
}
if (!password.equals(confirmPassword)) {
Toast.makeText(this, "Passwords do not match", Toast.LENGTH_SHORT).show();
return;
}
// Check for duplicate usernames
databaseReference.orderByChild("username").equalTo(username).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
Toast.makeText(RegistrationActivity.this, "Username already exists", Toast.LENGTH_SHORT).show();
} else {
// Check for duplicate phone numbers
databaseReference.orderByChild("phoneNumber").equalTo(phoneNumber).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot phoneSnapshot) {
if (phoneSnapshot.exists()) {
Toast.makeText(RegistrationActivity.this, "Phone number already used", Toast.LENGTH_SHORT).show();
} else {
// Register user in the Realtime Database
String userId = databaseReference.push().getKey();
String folderPath = "users/" + userId + "/";
User user = new User(username, phoneNumber, password, folderPath);
databaseReference.child(userId).setValue(user)
.addOnCompleteListener(dbTask -> {
if (dbTask.isSuccessful()) {
createUserFolder(userId);
Toast.makeText(RegistrationActivity.this, "Registration Successful", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(RegistrationActivity.this, "Registration Failed: " + dbTask.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(RegistrationActivity.this, "Error: " + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(RegistrationActivity.this, "Error: " + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void createUserFolder(String userId) {
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReference();
StorageReference userFolder = storageRef.child("users/" + userId + "/");
// Create a dummy file to initialize the folder
StorageReference dummyFile = userFolder.child("dummy.txt");
byte[] data = "This is a placeholder to create the folder".getBytes();
dummyFile.putBytes(data).addOnSuccessListener(aVoid -> {
// Successfully created folder, now update the database
databaseReference.child(userId).child("storagePath").setValue(userFolder.getPath())
.addOnFailureListener(e -> Toast.makeText(RegistrationActivity.this, "Failed to save storage path: " + e.getMessage(), Toast.LENGTH_SHORT).show());
}).addOnFailureListener(exception -> {
// Handle unsuccessful uploads
Toast.makeText(RegistrationActivity.this, "Failed to create user folder: " + exception.getMessage(), Toast.LENGTH_SHORT).show();
});
}
}
package com.example.best_csportal;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
import java.util.concurrent.TimeUnit;
import com.google.firebase.FirebaseException;
import android.util.Log;
import android.app.Activity;
public class PhoneVerificationActivity extends AppCompatActivity {
private EditText editTextCode;
private Button buttonVerify;
private FirebaseAuth mAuth;
private String phoneNumber;
private String verificationId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.phoneverification_activity);
mAuth = FirebaseAuth.getInstance();
editTextCode = findViewById(R.id.editTextCode);
buttonVerify = findViewById(R.id.buttonVerify);
// Retrieve the phone number passed from LoginActivity
phoneNumber = getIntent().getStringExtra("phoneNumber");
sendVerificationCodeToUser(phoneNumber);
buttonVerify.setOnClickListener(v -> {
String code = editTextCode.getText().toString().trim();
if (!code.isEmpty()) {
verifyVerificationCode(code);
}
});
}
private void sendVerificationCodeToUser(String phoneNumber) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
// Auto-verification logic here
signInWithPhoneAuthCredential(credential);
}
@Override
public void onVerificationFailed(FirebaseException e) {
Log.e("PhoneVerification", "Verification failed: " + e.getMessage());
Toast.makeText(PhoneVerificationActivity.this, "Verification failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken token) {
Log.d("PhoneVerification", "Code sent successfully");
PhoneVerificationActivity.this.verificationId = verificationId; // Save the verification ID for later use
}
}
);
}
private void verifyVerificationCode(String code) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
signInWithPhoneAuthCredential(credential);
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, task -> {
if (task.isSuccessful()) {
String sourceActivity = getIntent().getStringExtra("sourceActivity");
if ("RegistrationActivity".equals(sourceActivity)) {
Intent resultIntent = new Intent();
setResult(Activity.RESULT_OK, resultIntent);
finish();
} else if ("LoginActivity".equals(sourceActivity)) {
Intent intent = new Intent(PhoneVerificationActivity.this, UserMainActivity.class);
startActivity(intent);
finish();
}
} else {
Toast.makeText(PhoneVerificationActivity.this, "Verification failed: " + task.getException().getMessage(), Toast.LENGTH_LONG).show();
setResult(Activity.RESULT_CANCELED);
finish();
}
});
}
}
I tried rebuilding the project. I checked my dependencies. I also tried running the app on an Android phone that I paired with Android Studio. I also tried adding AppCheck to see if that works but nope.
Dingrat Kahlil John Roderick is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.