I am trying to add some users in my real time firebase data base, I want to check that by email address which is an User attribute, the problem is that it is adding duplicates. I have an button To add in my database
DAOUser daoUser = new DAOUser();//database accessObject
registerAccountButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (emailField.getText().toString().equals("") || passwordField.getText().toString().equals("") || repeatPasswordField.getText().toString().equals("")) {
Toast.makeText(getApplicationContext(), "Please complete all fields!", Toast.LENGTH_SHORT).show();
} else if (!Objects.equals(passwordField.getText().toString(), repeatPasswordField.getText().toString())) {
Toast.makeText(getApplicationContext(), "Passwords does not match!", Toast.LENGTH_SHORT).show();
} else {
addUser(daoUser, emailField.getText().toString(), passwordField.getText().toString());
}
}
});
The method to add in database:
public void addUser(DAOUser daoUser, String inputMail, String inputPassword) {
daoUser.getDatabaseReference().child("User").orderByChild("email").equalTo(inputMail).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
Toast.makeText(getApplicationContext(), "User already exists!", Toast.LENGTH_SHORT).show();
} else {
User newUser = new User(inputMail, inputPassword, false);
try {
daoUser.add(newUser).addOnSuccessListener(suc -> {
Toast.makeText(getApplicationContext(), "Successfully registered user!", Toast.LENGTH_SHORT).show();
}).addOnFailureListener(er -> {
Toast.makeText(getApplicationContext(), "Unable to register user!", Toast.LENGTH_SHORT).show();
});
} catch (UserIsNullException e) {
e.printStackTrace();
System.out.println("User is null");
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(getApplicationContext(), "User DataBase error !", Toast.LENGTH_SHORT).show();
}
});
}
The database looks like this:
Related
I would like to check if the user in the database exists. with this line of codes, it says that it exists and also that it does not exist. I want to make the code read-only if the name exists in one of the registers
enter image description here
Firebase database
private void Criar_Conta() {
databaseReference_users.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
if (snapshot.child("usuario").getValue().equals(Usuario.getText().toString()) && snapshot.getKey().equals(Usuario.getText().toString()) && snapshot.getKey().equals(snapshot.child("usuario").getValue())) {
Toast.makeText(Sign_Up.this, "Usuário Existente", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(Sign_Up.this, "Gravar ...", Toast.LENGTH_SHORT).show();
//Gravar_Dados();
}
}
} else {
Gravar_Dados();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(Sign_Up.this, databaseError.getMessage(), Toast.LENGTH_LONG).show();
Swipe.setRefreshing(true);
}
});
This is my code sample I hope this helps you
loginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String phoneTxt = phone.getText().toString();
final String passwordTxt = password.getText().toString();
if (phoneTxt.isEmpty() || passwordTxt.isEmpty()){
Toast.makeText(Login.this, "Please Enter Your Phone Number Or Password", Toast.LENGTH_SHORT).show();
}else {
databaseReference.child("users").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.hasChild(phoneTxt)){
final String getpassword = snapshot.child(phoneTxt).child("password").getValue(String.class);
if (getpassword.equals(passwordTxt)){
Toast.makeText(Login.this, "Successfully login! ", Toast.LENGTH_SHORT).show();
startActivity(new Intent(Login.this,HomeScreen.class));
finish();
}
else{
Toast.makeText(Login.this, "Wrong Password", Toast.LENGTH_SHORT).show();
}
}
else {
Toast.makeText(Login.this, "Wrong Phone Number!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
});
To be able to check if a specific user exists in the database, you should only perform a get(), and not attach a ValueEventListener. Assuming that the users are direct children of your Firebase Realtime Database root, in code, will be as simple as:
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
String usuario = Usuario.getText().toString();
DatabaseReference usuarioRef = db.child(usuario);
usuarioRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
DataSnapshot snapshot = task.getResult();
if(snapshot.exists()) {
Log.d("TAG", "User exists.");
} else {
Log.d("TAG", "User doesn't exist.");
}
} else {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
}
});
The problem I am facing is: when user 2 tries to access the same database collection, instead of showing that some data already exists in the database(the requirement is that data entered by the user 1 is saved in that same database), I get null in database. I could also figure out why it happened but clueless about how to query the firestore collection in such a way that different users save unique values for document fields "StartTime" and "EndTimes" in BookingInformation collection?
Following is the code I used;
FirebaseAuth fAuth = FirebaseAuth.getInstance();
String userId = fAuth.getCurrentUser().getUid();
Log.d(TAG,"userID: "+userId);
FirebaseFirestore fstore = FirebaseFirestore.getInstance();
DocumentReference docRef =
fstore.collection("BookingInformation").document(userId);
It happened that way because I have used userId as the document id of "BookingInformation" collection. By doing so, every time a new user login a new document is created. How should I solve it to make sure that when user 2 enters data it first checks that some document exists in the collection?
Edited:
Added code
NewBookingFragment.java
newBookingViewModel.getBookingInformation().observe(getViewLifecycleOwner(), new Observer<BookingInfo>() {
#Override
public void onChanged(final BookingInfo bookingInfo) {
Log.d(TAG,"hi from bookingInfodatabase");
Log.d(TAG,"content of bookingInfodatabase"+bookingInfo);
if (bookingInfo == null) {
Log.d(TAG,"no data from database, so add as a new");
Toast toast = Toast.makeText(getActivity().getApplicationContext(), "No data from database, so add as a new booking information", Toast.LENGTH_SHORT);
toast.show();
searchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast toast1 = Toast.makeText(getActivity().getApplicationContext(), "No data in database to compare!", Toast.LENGTH_SHORT);
toast1.show();
}
});
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "user id in fragment class: "+currentUserId);
final Map<String, Object> reserveInfo = new HashMap<>();
reserveInfo.put("Date",date.getText().toString());
reserveInfo.put("StartTime",startTime.getText().toString());
reserveInfo.put("EndTime",endTime.getText().toString());
reserveInfo.put("UserId",currentUserId);
dataStore.collection("BookingInformation").document(currentUserId).set(reserveInfo)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast toast4 = Toast.makeText(getActivity().getApplicationContext(), "Area reserved successfully", Toast.LENGTH_SHORT);
toast4.show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast toast5 = Toast.makeText(getActivity().getApplicationContext(), "Reservation failed", Toast.LENGTH_SHORT);
toast5.show();
}
});
}
});
}else{
searchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG,"after clicking available button");
Log.d(TAG,"booking id"+bookingInfo.getBookingDocId());
Log.d(TAG,"database time: "+bookingInfo.getStartTime());
Log.d(TAG,"user input time: "+startTime.getText().toString());
Log.d(TAG,"comparing time: "+bookingInfo.getStartTime().equals(startTime.getText().toString()));
if (bookingInfo.getDate().equals(date.getText().toString()) ){
Log.d(TAG, "Date check ");
if (bookingInfo.getStartTime().equals(startTime.getText().toString()) && bookingInfo.getEndTime().equals(endTime.getText().toString())) {
Toast toast = Toast.makeText(getActivity().getApplicationContext(), "Select another time.", Toast.LENGTH_SHORT);
toast.show();
Log.d(TAG, "start and end time check ");
if (bookingInfo.getStartTime().equals(startTime.getText().toString())) {
Log.d(TAG, "start time check ");
if (bookingInfo.getEndTime().equals(endTime.getText().toString())) {
Toast toast2 = Toast.makeText(getActivity().getApplicationContext(), "Select another end time.", Toast.LENGTH_SHORT);
toast2.show();
Log.d(TAG, "end time check ");
}
Log.d(TAG, "end time not equal check ");
}
Log.d(TAG, "start time not equal check ");
}
else{
Toast toast4 = Toast.makeText(getActivity().getApplicationContext(), "Area available at this time,'Book' it.", Toast.LENGTH_SHORT);
toast4.show();
availabletextView.setText("Area available");
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "user id in fragment class: "+currentUserId);
final Map<String, Object> reserveInfo = new HashMap<>();
reserveInfo.put("Date",date.getText().toString());
reserveInfo.put("StartTime",startTime.getText().toString());
reserveInfo.put("EndTime",endTime.getText().toString());
reserveInfo.put("UserId",currentUserId);
dataStore.collection("BookingInformation").document(currentUserId).set(reserveInfo)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast toast4 = Toast.makeText(getActivity().getApplicationContext(), "Area reserved successfully", Toast.LENGTH_SHORT);
toast4.show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast toast5 = Toast.makeText(getActivity().getApplicationContext(), "Reservation failed", Toast.LENGTH_SHORT);
toast5.show();
}
});
}
});
}
} else {
availabletextView.setText("Area available");
Log.d(TAG, "user id: "+currentUserId);
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "user id in fragment class: "+currentUserId);
final Map<String, Object> reserveInfo = new HashMap<>();
reserveInfo.put("Date",date.getText().toString());
reserveInfo.put("StartTime",startTime.getText().toString());
reserveInfo.put("EndTime",endTime.getText().toString());
reserveInfo.put("UserId",currentUserId);
dataStore.collection("BookingInformation").document(currentUserId).set(reserveInfo)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast toast4 = Toast.makeText(getActivity().getApplicationContext(), "Area reserved successfully", Toast.LENGTH_SHORT);
toast4.show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast toast5 = Toast.makeText(getActivity().getApplicationContext(), "Reservation failed", Toast.LENGTH_SHORT);
toast5.show();
}
});
}
});
}
}
});
}
}
});
NewBookingViewModel.java
public class NewBookingViewModel extends ViewModel {
private static final String TAG = "Firelog";
public LiveData<BookingInfo> getBookingInformation() {
final MutableLiveData<BookingInfo> bookingInfoMutableLiveData = new MutableLiveData<>();
FirebaseAuth fAuth = FirebaseAuth.getInstance();
String userId = fAuth.getCurrentUser().getUid();
Log.d(TAG,"userID: "+userId);
FirebaseFirestore fstore = FirebaseFirestore.getInstance();
DocumentReference docRef = fstore.collection("BookingInformation").document(userId);
Log.d(TAG,"docRef"+docRef);
String docid = docRef.getId();
Log.d(TAG,"document id"+docid);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG,"hi from viewmodel database");
DocumentSnapshot documentSnapshot = task.getResult();
Log.d(TAG, "Doc ID: "+documentSnapshot.getId());
Log.d(TAG,"document exist: "+documentSnapshot.exists());
if (documentSnapshot != null && documentSnapshot.exists()) {
String date = documentSnapshot.getString("Date");
String startTime = documentSnapshot.getString("StartTime");
String endTime = documentSnapshot.getString("EndTime");
BookingInfo bookingInfo = documentSnapshot.toObject(BookingInfo.class);
Log.d(TAG,"hi from viewmodel date: "+date);
bookingInfo.setDate(date);
bookingInfo.setStartTime(startTime);
bookingInfo.setEndTime(endTime);
bookingInfoMutableLiveData.postValue(bookingInfo);
} else {
bookingInfoMutableLiveData.postValue(null);
}
} else {
bookingInfoMutableLiveData.postValue(null);
}
}
});
return bookingInfoMutableLiveData;
}
}
Thanks.
I just figured out that to allow 2 or more users to enter and save data in the collection without any duplicate data w.r.t startTime and endTime field, I have to make sure that the document already exists or not. For that, as a solution, I counted the document in the collection.
Following is the code "NewBookingViewModel.java"
fstore.collection("BookingInformation")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
QuerySnapshot querySnapshot = task.getResult();
if (!querySnapshot.isEmpty()) {
for (QueryDocumentSnapshot queryDocumentSnapshot : task.getResult()) {
count++;
Log.d(TAG, "document count: "+count);
if (count != 0) {
String date = queryDocumentSnapshot.getString("Date");
String startTime = queryDocumentSnapshot.getString("StartTime");
String endTime = queryDocumentSnapshot.getString("EndTime");
BookingInfo bookingInfo = queryDocumentSnapshot.toObject(BookingInfo.class);
bookingInfo.setBookingDocId((queryDocumentSnapshot.getId()));
bookingInfo.setDate(date);
bookingInfo.setStartTime(startTime);
bookingInfo.setEndTime(endTime);
bookingInfoMutableLiveData.postValue(bookingInfo);
}else {
Log.d(TAG, "No booking data");
}
}
} else {
bookingInfoMutableLiveData.postValue(null);
}
} else {
bookingInfoMutableLiveData.postValue(null);
}
}
});
My app uses FirebaseAuth. In my SignInActivity, on clicking the sign in button, the signInWithEmailAndPassword onCompleteListener starts my DashboardActivity with an Intent. In the DashboardActivity, there is a method which calls FirebaseAuth.getInstance().getCurrentUser().getUid() which crashes my app if the user trying to signIn does not exist.
The question here is: why does the method get called at all if the Intent was not sent? or was the intent sent?
here is my SignInActivity signIn Button code:
signIn.setOnClickListener((new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!email.getText().toString().equals("") && !password.getText().toString().equals("")) {
showProgressBar();
FirebaseAuth.getInstance().signInWithEmailAndPassword(email.getText().toString(), password.getText().toString()).addOnCompleteListener((new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
hideProgressBar();
Toast.makeText(SignInActivity.this, "Signed In", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(SignInActivity.this, DashboardActivity.class);
startActivity(intent);
finish();
}
})).addOnFailureListener((new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
hideProgressBar();
Toast.makeText(SignInActivity.this, "Failed to Sign In", Toast.LENGTH_SHORT).show();
}
}));
} else {
Toast.makeText(SignInActivity.this, "please fill all fields", Toast.LENGTH_SHORT).show();
}
}
}));
DashboardActivity code (that crashes the app):
private void queryDB() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child(getString(R.string.users))
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.child("securityLevel");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String secLevel = dataSnapshot.getValue(String.class);
if (secLevel.equals("1")) {
fab.hide();
} else {
fab.show();
}
Log.d(TAG, "onDataChange: +-+ " + secLevel);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
The Logcat:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
at com.quwaysim.regapp.DashboardActivity.queryDB(DashboardActivity.java:191)
at com.quwaysim.regapp.DashboardActivity.onCreate(DashboardActivity.java:60)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127).......
OnComplete will execute even if the authorization passed or not. You need to add OnSuccessListener and handle the intent there.
You are not checking if task is successful or not. You have to do it like:
#Override
public void onClick(View view) {
if (!email.getText().toString().equals("") && !password.getText().toString().equals("")) {
showProgressBar();
FirebaseAuth.getInstance().signInWithEmailAndPassword(email.getText().toString(), password.getText().toString()).addOnCompleteListener((new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful() && task.getResult() != null){
hideProgressBar();
Toast.makeText(SignInActivity.this, "Signed In", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(SignInActivity.this, DashboardActivity.class);
startActivity(intent);
finish();
}
}
})).addOnFailureListener((new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
hideProgressBar();
Toast.makeText(SignInActivity.this, "Failed to Sign In", Toast.LENGTH_SHORT).show();
}
}));
} else {
Toast.makeText(SignInActivity.this, "please fill all fields", Toast.LENGTH_SHORT).show();
}
}
}));
private void userSign() {
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
String message = Objects.requireNonNull(task.getException()).getMessage();
Toast.makeText(Start.this, "Error occured: " + message, Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
else
{
Query DatabaseQuery = databaseReference.child("Users").child("Customer").orderByChild("email").equalTo(CLemail.getText().toString().trim());
DatabaseQuery.addListenerForSingleValueEvent(new ValueEventListener()
{
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
if (dataSnapshot.exists())
{
for (DataSnapshot user : dataSnapshot.getChildren())
{
User usersBean = user.getValue(User.class);
if (!usersBean.password.equals(CLpassword.getText().toString().trim()))
{
CLpassword.setError("Password is Wrong!");
CLpassword.requestFocus();
}
else
{
Intent intent = new Intent(Start.this, Home.class);
startActivity(intent);
dialog.setMessage("Loging please wait");
dialog.setIndeterminate(true);
dialog.show();
}
}
}
else {
Toast.makeText(Start.this, "User not found", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError)
{
Toast.makeText(Start.this, "Email not found", Toast.LENGTH_LONG).show();
}
});
dialog.dismiss();
Intent intent = new Intent(Start.this, Home.class);
startActivity(intent);
}
}
});
}
When I try to save a ParseObject in my Android app it does not seem to be saving to the Dashboard. There seems to be no error's showing. Here's my code.
N.B: The code is nested within protected void onCreate(Bundle savedInstanceState)
continue_reg.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
firstNameTxt = first_name.getText().toString();
lastNameTxt = last_name.getText().toString();
if (firstNameTxt.equals("") && lastNameTxt.equals("")) {
Toast.makeText(getApplicationContext(), "Please complete all fields", Toast.LENGTH_LONG).show();
} else {
ParseObject patientInfo = new ParseObject("PatientInformation");
patientInfo.put("firstName", firstNameTxt);
patientInfo.put("lastName", lastNameTxt);
patientInfo.saveInBackground();
Toast.makeText(getApplicationContext(), "Complete", Toast.LENGTH_LONG).show();
}
}
});
Try to use the SaveCallback(), so you can see if any error appears.
patientInfo.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
// No error, the object was saved
Toast.makeText(getApplicationContext(), "Complete", Toast.LENGTH_LONG).show();
} else {
// Error saving object, print the logs
e.printStackTrace();
}
}
});