Login using email stored in firebase realtime database - java

I am developing an android App in which I implemented Firebase realtime database. And now I want to login using by email id and password which stored in database. I know firebase auth can be use for authentication but I want to login using realtime database like we do in Sql or my sql.

I done this. First I fetch data of particular email id from database and than compare its password and assign the related function to do..
Query query = databaseReference.child("users").orderByChild("email").equalTo(txvUsername.getText().toString().trim());
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// dataSnapshot is the "issue" node with all children with id 0
for (DataSnapshot user : dataSnapshot.getChildren()) {
// do something with the individual "issues"
UsersBean usersBean = user.getValue(UsersBean.class);
if (usersBean.password.equals(txvPassword.getText().toString().trim())) {
Intent intent = new Intent(context, MainActivity.class);
startActivity(intent);
} else {
Toast.makeText(context, "Password is wrong", Toast.LENGTH_LONG).show();
}
}
} else {
Toast.makeText(context, "User not found", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Thanks..

I am assuming that you know how to use ValueEventListener, onDataChange method and Datasnapshot.
As you stated above, you want to do it like in SQL or MySQL. So instead of using email, I will use username and password.
You can authenticate your user without using Firebase Authentication. However, this is not recommended for the database security.
{
"userList": {
"JRHTHaIsjNPLXOQivY": {
"userName": "userA",
"password": "abc123"
},
"JRHTHaKuIFIhnj02kE": {
"userName": "userB",
"password": "abc123"
}
},
"userAuth": {
"userA": "JRHTHaIsjNPLXOQivY",
"userB": "JRHTHaKuIFIhnj02kE"
}
}
As you can see above I have saved the the userName and userId in firebase db. When a user enter the username and password, you should read the userId by using username in the userAuth. Once you have retrieved the userID, use it to access the userList for the user details. This is where you check for the entered password.
{
"userList": {
"userA": {
"password": "abc123"
},
"userB": {
"password": "abc123"
}
}
}
Or you can just authenticate your users like this.

Related

How can I store FireBase Cloud Messaging tokens in firebase database in Android?

I am building a chat application and using FCM services.
When the user signs up on the app I am able to get the token by
String token1; FirebaseMessaging.getInstance().getToken()
.addOnCompleteListener(new OnCompleteListener<String>() {
#Override
public void onComplete(#NonNull Task<String> task) {
if (!task.isSuccessful()) {
Log.w("TTTTTTTTTTTT", "Fetching FCM registration token failed", task.getException());
return;
}
// Get new FCM registration token
token1 = task.getResult(); //this is the token
// Log
Log.d("TTTTTTTTTTTT", token1);
}
});
Now, after getting the token I want to store it in Firebase Database along with the associated user.
So the User would have a email, a password , a city and a token.
signUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String em = email.getText().toString();
String pass = password.getText().toString();
final String na = name.getText().toString();
final String ci = city.getText().toString();
if (em.equals("") || pass.equals("") || na.equals("") || ci.equals("")) {
name.setError("Enter your name");
password.setError("Enter your password");
city.setError("Enter your city");
email.setError("Enter your email");
Toast.makeText(ActivitySignup.this, "Please fill all the Fields", Toast.LENGTH_SHORT).show();
} else {
progressBar.setVisibility(View.VISIBLE);
FirebaseAuth.getInstance().createUserWithEmailAndPassword(em, pass).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
progressBar.setVisibility(View.GONE);
FirebaseDatabase.getInstance().getReference().child("USERS").
child(task.getResult().getUser().getUid()).
setValue(new UserModel(em, na, ci,token1 )); //Creating a new user and storing name ,email, city and token in database
startActivity(new Intent(ActivitySignup.this, YearChooseActivity.class).putExtra("activity_name", "ActivitySignUp")
.putExtra("timesVisited", timesVisited));
Toast.makeText(ActivitySignup.this, "Successfully Register User \n" + em, Toast.LENGTH_SHORT).show();
} else {
progressBar.setVisibility(View.GONE);
Toast.makeText(ActivitySignup.this, Objects.requireNonNull(Objects.requireNonNull(task.getException()).getMessage()).toString(), Toast.LENGTH_LONG).show();
}
}
});
}
}
});
FirebaseDatabase.getInstance().getReference().child("USERS").child(task.getResult().getUser().getUid()).setValue(new UserModel(email, name, city , token1 )); //Creating a new user and storing name ,email,
The problem is that the token does not gets stored in Firebase. When I pass a random String as the token parameter lets say I pass " Kobe will be remembered" as the argument
FirebaseDatabase.getInstance().getReference().child("USERS").child(task.getResult().getUser().getUid()).setValue(new UserModel(email, name, city ," Kobe will be remembered" )); //Creating a new user and storing name ,email,
Then it gets stored in the database pretty well.
When I sign up with a test user let's say name=a , email = a#gmail.com , city = a then in the realtime database the token is not saved. This is how the realtime database looks.
"aBnS2fuXo2gmvcxzqy3z3mgFpiv2" : {
"city" : "a",
"email" : "a#gmail.com",
"name" : "a"
}
But when I hardcode the token value to a random string lets say "Arnold" by using FirebaseDatabase.getInstance().getReference().child("USERS").child(task.getResult().getUser().getUid()).setValue(new UserModel(email, name, city ,"Arnold" ));
then the database looks like
"aBnS2fuXo2gmvcxzqy3z3mgFpiv2" : {
"city" : "a",
"email" : "a#gmail.com",
"name" : "a"
"userToken" : "Arnold",
}
For notification I need the token for the opposing party, hence how do I store the token of all users in firebase along with their other credentials ?
you definitely don't store them in the same location it's not good security practice. also, the user may sign out or change their phones you don't want to send the notifications to the old device.
save the FCM token under the user information or a subcollection.
then if you want to message them using that token you just use their UID to get their token and send them a message. You can securely do that using cloud functions.

How to check if user entered userid already exists in the firebase through java?

I've tried so many ways to check if a user id is already in the firebase but all method are in vain.
Below is my code to check if user id exists but whatever data I enter it does not show the required error.
userid = findViewById(R.id.userid);
String userVal = userid.getEditText(). getText().toString();
boolean userquery = FirebaseDatabase.getInstance().getReference().child("user").orderByChild("userid").equals(userVal);
if(userquery) {
userid.setError("This user name already exists");
return;
}
Whenever I try to add existing value in the input it accepts the value and overwrites in the database.
Here is the screenshot of my firebase database.
Your code so far only sets up a query. It doesn't actually execute the query, so there's no way it can detect whether the data exists. To execute a query, you have to attach a listener to it.
So in your case, that could be something like:
boolean userquery = FirebaseDatabase.getInstance().getReference().child("user").orderByChild("userid").equals(userVal);
userquery.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 if (task.getResult().exists()) {
userid.setError("This user name already exists");
}
}
});
On older SDK versions the equivalent would be:
boolean userquery = FirebaseDatabase.getInstance().getReference().child("user").orderByChild("userid").equals(userVal);
userquery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
userid.setError("This user name already exists");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}

After creating a user with email and password with Android Firebase I cannot save additional information in a users collection

After creating a user using the firebaseAuth function createUserWithEmailAndPassword (email, password) I am trying to save additional information of the users that are registered in a collection called "users". For that I use DocumentReference:
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
FirebaseUser fuser = FirebaseAuth.getInstance().getCurrentUser();
String idUser = fuser.getUid();
DocumentReference documentReference = fStore.collection("users").document(fuser.getUid());
Map<String, Object> user = new HashMap<>();
Log.d("data", "username: "+username + " telef: "+telefono);
user.put("username", username);
user.put("telefono", telefono);
documentReference.set(user).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "User profile created");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "can´t create profile: "+e.toString());
}
});
//sign out the user.. dont work.. any ideas?
FirebaseAuth.getInstance().signOut();
mProgressBar.dismiss();
//send the user to log in
Intent intent = new Intent(RegisterActivity.this, loginActivity.class);
//intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
RegisterActivity.this.finish();
Toast.makeText(getApplicationContext(), "Registered ok!", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(), "can´t register", Toast.LENGTH_LONG).show();
}
}
});
Apart from having instantiated:
mAuth = FirebaseAuth.getInstance();
fStore = FirebaseFirestore.getInstance();
I have also been forced to add the following:
private void initFirebase() {
FirebaseApp.initializeApp(this);
firebaseDatabase = FirebaseDatabase.getInstance();
firebaseDatabase.setPersistenceEnabled(true);
databaseReference = firebaseDatabase.getReference();
}
Not even with the latter it works. Only the user with email and password is registered. The strange thing is that there is no error, it seems that the onSuccess or onFailure event does not occur. The database rules in the firebase console are:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
Basically this rule indicates that the user must be authenticated to be able to read / write to the database. My dependencies are:
implementation 'com.google.firebase:firebase-auth:19.3.0'
implementation 'com.google.firebase:firebase-firestore:21.4.2'
implementation 'com.google.firebase:firebase-storage:19.1.1'
implementation 'com.google.firebase:firebase-database:18.0.1'
I should use firebase-firestore and firebase-auth but I have added firebase-database and firebase-storage in order to solve the problem but nothing happens.
Thanks in advance.
Your code is signing out the user before the database is written, so the write will fail any database rules that require the user to be signed in.
documentReference.set(user) is asynchronous and returns immediately, before any work has been done. The database will be written some time later. Meanwhile, your code goes on to immediately execute a signout with FirebaseAuth.getInstance().signOut(), which deletes the user's auth token, making the query happen without any credentials.
If you need the user to be signed out after writing the database, you should do that inside the database callback code. Though it's entirely clear to me why you would want that to happen. You should probably just remove the signout completely.

Finding a user data based on email

i have gotten the email of a user in LoginPage, now i want to get his data (the users data include: mobile number ,name,bday date and most importantly type(business/regular)), based on the type i can know where should i redirect the user (if the user's type is business then ill send hime to the BusinessHomeActivity..)
you can see my database structure (each UID contains email,bday,type,mpbile number) which is the user's info
i hope you can help me
(Java,android studio)
thank you!
It's simple you can get this UID like this
FirebaseAuth.getInstance().signInWithEmailAndPassword(email, password)
.addOnCompleteListener(getActivity(), task -> {
if (task.isSuccessful()) {
// here you get the logged-in user UID if login successful
String userUID = FirebaseAuth.getInstance().getCurrentUser().getUid()
// set the path of your database and get the UID from it
String path = FirebaseDatabase.getInstance().getReference("yourRootKey").child("User").child(userUID).child("Email")
//add a listener to get value
path.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// here you can get value from dataSnapshot as above you can achieve from onDataChange and check the type
// and navigate to user
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("onCancelled", databaseError.toException());
}
});
} else {
// login failed display as toast
}
});

Implementing user-based security in Android Firebase

When logging into my application as user, I want said user to have access to their own particular maintenance records. Presumably, this would be done using the UID that is generated once the user has signed up to the application using Firebase Auth.
MaintenanceActivity
private boolean updateMaintenance(String title, String desc, String id, String primary, String secondary, String property) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("maintenance").child(id);
Maintenance maintenance = new Maintenance (id, title, desc, primary, secondary, property);
databaseReference.setValue(maintenance);
Toast.makeText(this, "Maintenance Updated Updated Successfully", Toast.LENGTH_LONG).show();
return true;
}
private void addMaintenance(){
String title = editTextTitle.getText().toString().trim();
String desc = editTextDesc.getText().toString().trim();
String primary = spinnerPrimary.getSelectedItem().toString();
String secondary = spinnerSecondary.getSelectedItem().toString();
String property = spinnerProperty.getSelectedItem().toString();
if(!TextUtils.isEmpty(title)){
String id = databaseMaintenance.push().getKey();
Maintenance maintenance = new Maintenance (id, title, desc, primary, secondary, property);
databaseMaintenance.child(id).setValue(maintenance);
Toast.makeText(this, "Maintenance Added", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "You must enter a maintenance record", Toast.LENGTH_LONG).show();
}
}
LoginActivity
This is what I have implemented at the moment. Currently, I can log in using the Firebase-stored credentials, however, the maintenance records that are held in the Firebase database always shown. No matter who is logged in.
Auth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
Database Rules
I have set my database rules up as follows:
{
"rules": {
"users": {
"$uid": {
".write": "$uid === auth.uid",
".read": "$uid === auth.uid"
}
}
}
}
Current Firebase Database
These are the maintenance cases that are showing when logged in as any user.
Not sure if my MaintenanceActivity code is required here and, if so, which parts.
Any help on this would be massively appreciated, have been stuck on this for so long now.
Many thanks.
To fetch only logged in user records in firebase ..
First add security rules in Firebase console.
match /databases/{database}/documents {
match /maitenance/{userId} {
allow read, write: if request.auth.uid == userId;
}
}
Then, you need to add user id node as child of maintenance node, user maintenance records should be children of the logged in user id node.
Finally, in the read operation pass user id to fetch maintenance records of user id.
firestoreDB.collection("maintenance")
.whereEqualTo("userId", userId)
.get()
Please see how user specific data is saved in and fetched from firestore database. You can do same with realtime database as well.

Categories