Android search in Firebase database - android

I would like to ask for help in a problem that I want to search for e-mail, according to the database, but it fails to process the received data. I want to receive something of value that the email is already in the database or not.
How do I process the result? Here's the code which try:
DatabaseReference reg = FirebaseReferenciak.reg;
reg.orderByChild("email").equalTo("email", etEmail.getText().toString()).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, String> map = dataSnapshot.getValue(Map.class);
String value = map.get("name");
//Here is how do I check?
//String value = dataSnapshot.getValue(String.class);
dialog(value);
}
#Override
public void onCancelled(DatabaseError databaseError) {
dialog("error");
}
}
);
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.
For that reason you'll need to loop over the children of the DataSnapshot that you receive in onDataChange():
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String value = childSnapshot.child("name").getValue(String.class);
dialog(value);
}
}

Related

How to retrieve data from a list of children that I don't know the name of in advance?

Hi I am very new to Firebase and Java and I am looking for a hopefully easy answer. This is my database:
In my code the user inputs a name and number from separate text fields. I use the name to generate a child in "Client." What I want to do is take the "Name" and "Number" values and output them into text on my application. Problem is I am having a hard time figuring out how to reference the children of Client to output the data. Alex, David, Will are just placeholders for really any value the user inputs so how do I reference a child I don't know the name of?
First retrieve your Client datasnapshot
//Get datasnapshot at your "users" root node
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Client");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Get map of users in datasnapshot
collectInfo((Map<String,Object>) dataSnapshot.getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
Then loop through clients, accessing their map
private void collectInfo(Map<String,Object> clients) {
//iterate through each client
for (Map.Entry<String, Object> entry : clients.entrySet()){
//Get client map
Map singleClient = (Map) entry.getValue();
// Do whatever you want to do with single clients
}
}
Here's a simple way:
DatabaseReference clientsRef = FirebaseDatabase.getInstance().getReference().child("Client");
clientsRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot clientSnapshot: dataSnapshot.getChildren()) {
System.out.println(clientSnapshot.getKey()); // "Alex", "David", "Will"
System.out.println(clientSnapshot.child("Name").getValue(String.class)); // "Alex", "David", "Will"
System.out.println(clientSnapshot.child("Number").getValue(String.class)); // "12345", "98765", "12345"
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
If you are just getting started with Android development and Firebase, I recommend taking this codelab first. It will save you much time (and questions) going forward.

To get children value before child in firebase database

Here's my structure of database for storing the latitude, longitude and subject under username. Now i am the current user of slocation and I want to find the same subject as my subject in tlocation user. I know for loop can find the same subject but if detect the same subject then how do i get the username of the same subject?
Please advice me if my thinking insertion to database got error. Thank you.
You'll need to use a query to get the nodes from tlocation.
String subject = "P - mathematics";
DatabaseReference tlocationRef = FirebaseDatabase.getInstance().getReference("tlocation");
Query subjectQuery = tLocatinRef.orderByChild("subject").equalTo(subject);
subjectQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot userSnapshot: dataSnapshot.getChildren()) {
System.out.println(userSnapshot.getKey());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
})
Also see:
Listen for Value events for a query
Listen for Child* events for a query
Sorting and filtering data

Updating Firebase Database with nodes created with push

I am trying to update a value in my Firebase database. This is the structure of the database:
I need to update the value of status to "accepted" if the r_id and s_id have a specific value. The problem here is that the key for each friend_data child is generated using "push" like this
db.child("friend_data").push().setValue(friend);
I have tried this question here and this one here but both don't meet my requirements. How do I go about solving this one?
Edit: I understand now that I am supposed to use a Query here. This is what I tried:
final DatabaseReference db = FirebaseDatabase.getInstance().getReference("friend_data");
Query query = db.orderByChild("r_id").equalTo(f_id).orderByChild("s_id").equalTo(id);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
db.child(child.getKey()).child("status").setValue("accepted");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
This does not work either because this error is raised
java.lang.IllegalArgumentException: You can't combine multiple orderBy calls!.
So how do I combine two Queries?
I have finally got this to work after days of trying to figure it out.
I added a Query with orderByChild method to filter out a big chunk of data at the server side itself (thanks to this answer for the idea.) The remaining data which I got as child of data type DataSnapshot had all the necessary information that I needed. Here is the query
Query query = db.orderByChild("r_id").equalTo(f_id);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
String child_s_id = (String) child.child("s_id").getValue();
String child_status = (String) child.child("status").getValue();
if (child_s_id.equals(id)) {
Log.e("Got value", f_id + " - x -" + id + " " + child_status);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
But again I could not meet my requirements, because I actually needed to modify one of the value in the child and I could not use any methods like setValue to change the value of child.
Again, it took me a long while (what an idiot) to figure out that I had to convert the child (of data type DataSnapShot) to a reference for setValue to work. And it worked
child.getRef().child("status").setValue("accepted");
Here is the completed code. Hope it helps someone along the way
Query query = db.orderByChild("r_id").equalTo(f_id);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
String child_s_id = (String) child.child("s_id").getValue();
String child_status = (String) child.child("status").getValue();
if (child_s_id.equals(id))
child.getRef().child("status").setValue("accepted");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Firebase user details are not retrieved in Android

I am storing user details 'firstname' and 'lastname' in UserNode. But when i want to retrieve that details then no data is being retrieved. I tried almost all solutions on the internet but nothing solved my problem. Here is my code for retrieving data of the current user:
FirebaseUser userr = FirebaseAuth.getInstance().getCurrentUser();
if (userr != null) {
String name = userr.getDisplayName();
Log.e("value", name);
}
but it says "println needs a message"
I also tried with this but nothing happened:
DatabaseReference DataRef;
DataRef = FirebaseDatabase.getInstance().getReference().child("UserNode");
DataRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String acctname = (String)dataSnapshot.child("firstname").getValue();
Log.e("name", acctname);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
]1
Please help me I am stuck with it
You're reading a collection of user with a ValueEventListener. As the [Firebase documentation for reading lists with a value event](Listen for value events) explains:
While using a ChildEventListener is the recommended way to read lists of data, there are situations where attaching a ValueEventListener to a list reference is useful.
Attaching a ValueEventListener to a list of data will return the entire list of data as a single DataSnapshot, which you can then loop over to access individual children.
Even when there is only a single [child node], the snapshot is still a list; it just contains a single item. To access the item, you need to loop over the result.
So in your code:
DatabaseReference DataRef;
DataRef = FirebaseDatabase.getInstance().getReference().child("UserNode");
DataRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String acctname = (String)childSnapshot.child("firstname").getValue();
Log.i("name", acctname);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Using FirebaseUser:
FirebaseUser implements UserInfo and in UserInfo's getDisplayName() documentation says
Returns the user's display name, if available.
So, it is possible that FirebaseUser.getDisplayName() return null when display name is not set. In that case Log.e() receives null as message and therefore prints println needs a message
Using your own structure:
Instead of using type conversion use getValue(Class<T>) like so:
String acctname = dataSnapshot.child("firstname").getValue(String.class);
Please, read how to retrieve data from firebase. I think you have a problem because you don't have Class Model.
Your steps:
Create model UserModel with firstname and lastname field
Use listener (example from docs):
// Attach a listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Post post = dataSnapshot.getValue(Post.class);
System.out.println(post);
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
See other answers: How to retrieve data from one single userID Firebase Android and retrieving data from firebase android

Get element by key with Firebase

I've been trying to retrieve an element from my Firebase database using its key. I have a class User and users are present in database.
I want to retrieve an object user using its key with this method :
public User getConnectedUserByUId(final String uid){
DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = database.child("users");
final List<User> connectedUser= new ArrayList<User>();
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot item: dataSnapshot.getChildren()) {
if (item.getKey()==uid)
{
User user= dataSnapshot.getValue(User.class);
connectedUser.add(user);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return connectedUser.get(0);
}
but it returns an empty list every time.
The issue is here:
if (item.getKey()==uid)
since you are comparing 2 String in java you have to use the method
string.equals(Object other) not the == operator.
Moreover, since you know the key of the data in Firebase you can use it to get the reference without cycling all children.
Something like:
DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = database.child("users").child(uid);
Here you try to check a very specific ID only on changed data. Instead, try using a Firebase Query with filterByKey and not using your own function to achieve that. Here's sample code that I would use to try to replace your function:
DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = database.child("users");
Query connectedUser = ref.equalTo(uid);
connectedUser.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
// TODO: handle the post here
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
// ...
}
});
As specified in the Firebase documentation here: https://firebase.google.com/docs/database/android/lists-of-data#filtering_data
in the line : User user= dataSnapshot.getValue(User.class);
you have to put : User user= item.getValue(User.class);
and you have to check the id after you get the user:
if (user.getKey()==uid){
connectedUser.add(user);
}
There are 2 mistakes and a minor issue:
you are using == to compare two String objects. In java, this is true only if they are the same reference. Use equals instead.
addValueEventListener only adds a listener that gets invoked once after you add it and then every time something changes in the value you are listening to: this is an asynchronous behaviour. You are trying to get data synchronously instead. Please read something about this.
you are fetching useless data: you only need an object but you are fetching tons of them. Please consider to use the closest reference you can to the data you are fetching.
So, in conclusion, here's some code. I'd like to point out right now that forcing synchronous acquisition of naturaly asynchronous data is a bad practice. Nevertheless, here's a solution:
public User getConnectedUserByUId(final String uid){
DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = database.child("users").child(uid);
Semaphore sem = new Semaphore(0);
User[] array = new User[1];
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot item: dataSnapshot.getChildren()) {
if (item.getKey()==uid)
{
User user= dataSnapshot.getValue(User.class);
array[0] = user;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
try
{
sem.tryAcquire(10, TimeUnit.SECONDS);
}
catch (Exception ignored)
{
}
return array[0];
}
EDIT: I've just seen that this post is very old. I'm not sure how I ended up here.

Categories

Resources