Firebase get uid from email - java

I would like to get a uid from inputing an email for making it possible to add friends with an email.
Here is what I have gotten so far:
final DatabaseReference mRef = FirebaseDatabase.getInstance().getReference().child("users");
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
final String currentUserUid = user.getUid();
mRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild(uid)) {
DatabaseReference newRef = mRef.child(uid);
newRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (!dataSnapshot.hasChild(uid)) {
DatabaseReference database = FirebaseDatabase.getInstance().getReference();
String username = String.valueOf(dataSnapshot.child("username").getValue());
String email = String.valueOf(dataSnapshot.child("email").getValue());
String firebaseToken = String.valueOf(dataSnapshot.child("firebaseToken").getValue());
Friend friend = new Friend(uid, username, email, firebaseToken);
database.child(Constants.ARG_USERS)
.child(currentUserUid)
.child(Constants.ARG_FRIENDS)
.child(uid)
.setValue(friend)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
mOnFriendDatabaseListener.onSuccess(context.getString(R.string.friend_successfully_added));
} else {
mOnFriendDatabaseListener.onFailure(context.getString(R.string.friend_unable_to_add));
}
}
});
} else {
Log.d("Adding Friend", "User already not exist");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
} else {
Log.d("Adding Friend", "User does not exist");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
This works if I input an uid directly but I would like to have my input be an email and get an uid out from it, or if there are other solutions please suggest.
This is how the database structure looks like:
Thanks for the help in advance.

To search for a user by their email address you need to order/filter on that property:
Query query = mRef.orderByChild("email").equalTo("example#example.com");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// There may be multiple users with the email address, so we need to loop over the matches
for (DataSnapshot userSnapshot: dataSnapshot.getChildren()) {
System.out.println(userSnapshot.getKey());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "find email address:onCancelled", databaseError.toException());
// ...
}
});
Not directly related to the question, but please restructure your data to remove the nesting of friends and profiles. For many reasons it's best to keep your Firebase data structure flat and separate user profiles from friends lists.
/users
uid1: ... profile for user 1
uid2: ... profile for user 2
/friends
uid1: ... friends list for user 1
uid2: ... friends list for user 2

Related

On Android, how do you get the data from an email address in Firebase, then access the child, and from there you access the other Firebase data?

The following file explains better what I really mean. It's a screenshot of data sent from a dummy user in Firebase:
The code:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Users");
// ref.addValueEventListener(new ValueEventListener() {
ref.orderByChild("Email").equalTo("testing3#testing.com").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
String key = datas.getKey();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Users").child(key);
Toast.makeText(getApplicationContext(), key, Toast.LENGTH_LONG).show();
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String name = dataSnapshot.child("Name").getValue().toString();
String state = dataSnapshot.child("State").getValue().toString();
String stateRegion = dataSnapshot.child("StateRegion").getValue().toString();
String telephone = String.valueOf(dataSnapshot.child("Telephone").getValue());
nameEditText.setText(name);
stateEditText.setText(state);
stateRegionEditText.setText(stateRegion);
telephoneEditText.setText(telephone);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
});
Please, can some person help?
More information about data stored in the Firebase:
Because I cannot see a more detailed database schema of yours, I assume that all those user objects are direct children under your Users node, and also assuming that you want to find the user that has the Email set to testing3#tesing.com, to display his particular details, please use the following lines of code:
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = db.child("Users");
Query queryUsersByEmail = usersRef.orderByChild("Email").equalTo("testing3#testing.com");
queryUsersByEmail.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot ds : task.getResult().getChildren()) {
String name = ds.child("Name").getValue(String.class);
Log.d("TAG", name);
String state = ds.child("State").getValue(String.class);
Log.d("TAG", state);
String stateRegion = ds.child("State Region").getValue(String.class);
Log.d("TAG", stateRegion);
String telephone = ds.child("Telephone").getValue(String.class);
Log.d("TAG", telephone);
}
} else {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
}
});
The result in the logcat will be:
Paul SMith
Rio de Janeiro
Rio de Janeiro
(00)00000-0000

firebase realtime database push infinite loop error

I'm using firebase authentication with email and password.
So I want to save user data in realtime database .
But when i push the data to database, infinite loop was executing.
I don't know why..
I want to save data like this form and continue saving.
But when I starting, infinite loop is starting
private void createUser(String email, String password,String name, String phone, String
nickname) {
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) { //Join Success
Toast.makeText(JoinActivity.this, "Join Success", Toast.LENGTH_SHORT).show();
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(firebaseAuth.getCurrentUser()!=null) {
String email=editTextEmail.getText().toString().trim();
FirebaseUser user=firebaseAuth.getCurrentUser();
String uid=user.getUid();
if(dataSnapshot.child("USER").child("user_info").child(uid).exists()){
Toast.makeText(JoinActivity.this,"already exist",Toast.LENGTH_SHORT).show();
}else{
User user_info = new User(uid, editTextId.getText().toString(), editTextEmail.getText().toString(), editTextPassword.getText().toString(),
editTextname.getText().toString(), editTextNickname.getText().toString(), editTextPhone.getText().toString());
//delete all data
mDatabase.setValue(null);
String key = mDatabase.child("USER").push().getKey();
// mDatabase.child("USER").child("user_info").child(key).setValue(user_info);
Toast.makeText(JoinActivity.this, "save the data", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Intent intent = new Intent(JoinActivity.this, MainActivity.class);
startActivity(intent);
} else { //already exists
Toast.makeText(JoinActivity.this, "already exists", Toast.LENGTH_SHORT).show();
return;
}
}
});
}
}
Instead of :
mDatabase.addValueEventListener(new ValueEventListener() {
Use the following:
mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
This way you will retrieve data only once.

How to add data in pre-existing document by searching for specific node in Firebase? (Android)

There is one document which is student profile with student data like course, username, status etc.
I want to add another node named uid in pre-existing document by searching for emailid
For example, In document containing emailid: "abc#gmail.com" I want to add uid:"111032" in that document containing emailid.
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
final DatabaseReference studentRef = rootRef.child("STUDENT");
lg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
username = un.getText().toString().trim();
String password= pw.getText().toString().trim();
lg.setText("Logging in...");
firebaseAuth.signInWithEmailAndPassword(username, password)
.addOnCompleteListener(Welcome.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
firebaseAuth = FirebaseAuth.getInstance();
final String current_user_id = firebaseAuth.getCurrentUser().getUid();
//Save UID to database
Query emailAddressQuery = studentRef.orderByChild("emailid").equalTo(username).limitToFirst(1);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Map<String, Object> uidUpdate = new HashMap<String, Object>();
uidUpdate.put("uid", current_user_id);
ds.getRef().updateChildren(uidUpdate);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
emailAddressQuery.addListenerForSingleValueEvent(valueEventListener);
Intent i=new Intent(Welcome.this,Home.class);
// i.putExtra("useremail", username);
startActivity(i);
lg.setText("Log In");
} else {
Toast.makeText(getApplicationContext(), "Log In Failed", Toast.LENGTH_SHORT).show();
lg.setText("Log in");
}
// ...
}
});
}
});
The above code is actually is in sign in button which sign in the user get the uid and save it to that specific profile's info.this is the image with more detailed information.
As shown in this image, I want to search by emailid (Shown in yellow) and add node called uid in that specific document.
OLD CODE :
username = un.getText().toString().trim();
firebaseAuth = FirebaseAuth.getInstance();
String current_user_id = firebaseAuth.getCurrentUser().getUid();
ref= FirebaseDatabase.getInstance().getReference().child("STUDENT").child(username);
Map<String, Object> updates = new HashMap<String, Object>();
updates.put("uid", current_user_id);
ref.updateChildren(updates);
This code works but we have to pass the name of document while I want to pass data by child node in the document.
To solve this problem, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference studentRef = rootRef.child("STUDENT");
Query emailAddressQuery = studentRef.orderByChild("emailid").equalTo("abc#gmail.com").limitToFirst(1);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Map<String, Object> uidUpdate = new HashMap<String, Object>();
uidUpdate.put("uid", uid);
ds.getRef().updateChildren(uidUpdate).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d("TAG", "task is successful!");
} else {
Log.d("TAG", task.getException().getMessage());
}
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
emailAddressQuery.addListenerForSingleValueEvent(valueEventListener);
The result of this operation will be the update of the uid in the user object.

To get data of authenticated user failure

public void loadUserInformation() {
final String uid = mAuth.getCurrentUser().getPhoneNumber();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("Users");
// DatabaseReference uidRef = rootRef.child("ref").child(uid);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot: dataSnapshot.getChildren()){
String name=postSnapshot.child("Name").getValue().toString();
// String email=postSnapshot.child("Email").getValue().toString();
Name.setText(name);
// Email.setText(email);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getActivity(),"Error Loading UserDetails",Toast.LENGTH_LONG).show();
}
};
rootRef.addListenerForSingleValueEvent(eventListener);
}
I know why I'm not getting the expected results, its because there's one more child after users. I'm not sure on how to access it, child(uid) gave me a NullPointerException. The present code gives me name of some random user. I want it to return name of the authenticated user i.e. myself
Database - http://ibb.co/iRnF77
Change the phone number to the userid:
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
String userid=user.getUid();
So you will have this database:
Users
userid
Name: namehere
Phone_Number: numberhere
//etc
then you can simply retrieve the data of the current user:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("Users").child(userid);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name=dataSnapshot.child("Name").getValue().toString();
Name.setText(name);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
You don't need the phone number to be the parent node since you already have it as an attribute Phone_Number: number_here, no need to write it twice.
Also getPhoneNumber() can be used if you did phone authentication:
https://firebase.google.com/docs/auth/android/phone-auth

Getting values from Firebase

I'm new to Firebase, and decided to get my feet wet. However, I'm having trouble retrieving values from a query. I'm basically trying to get the password value, but I believe it's returning nothing.
Error:
java.lang.NullPointerException: println needs a message
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String username = usernameField.getText().toString();
String password = passwordField.getText().toString();
db.child("Users").orderByChild("username").equalTo(username).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
//Get the password,and check it against the password field
Map<String, String> map = (Map<String, String>)dataSnapshot.getValue();
Log.d("result", map.get("password"));
} else {
Toast.makeText(getApplicationContext(), "Incorrect login details", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
I know this isn't very practical, but like I said I'm only practicing.
Thanks for the help!
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
The code in your onDataChange needs to take care of the fact that the snapshot is a list, by looping over its snapshot.getChildren():
db.child("Users").orderByChild("username").equalTo(username).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
//Get the password,and check it against the password field
Map<String, String> map = (Map<String, String>)snapshot.getValue();
Log.d("result", map.get("password"));
}
}
Sine your database structure is different than your reference in your code you should change some things
First your Reference to the data should be like this
db.child("Users").child(uid).child("password").addValueEventListener...
Where uid is the result of
private FirebaseAuth mAtuh;
mAuth = FirebaseAuth.getCurrentUser().getUid();
String uid = mAuth ;
Check the official doc on how to properly authenticate users
https://firebase.google.com/docs/auth/android/manage-users
Also you can implement google sign-in :
https://firebase.google.com/docs/auth/android/google-signin
And then you can retrieve your password field like this
// Attach a listener to read the data
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String password = dataSnapshot.getValue(String.class);
Log.e("The password is:",""+password);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("Error getting the password",""+databaseError.getCode());
}
});
Hardcoding your reference without mAuth will be like this
db.child("Users").child("L7VR2mGZKnbReFqOlmP").child("password").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
String password = dataSnapshot.getValue(String.class);
Log.e("The password is:",""+password);
}else
{
Toast.makeText(getApplicationContext(), "Incorrect login details", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("Error getting the password",""+databaseError.getCode());
}
});
Hope it helps
happy coding

Categories

Resources