I have to receive a username that has a fullName equal to "Bobby". So I'm trying to get data from Firebase Database using the following syntax:
ref.orderByChild("fullName").equalTo("Bobby").addListenerForSingleValueEvent(new ValueEventListener() {...}
What I get from dataSnapshot.getValue() is this:
{id3={username=bob, score=150, fullName=Bobby}}
I would like to know what is the best or correct way to get the username if I do not know which id number was returned?
Currently I'm achieving it this way:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("Scores");
ref.orderByChild("fullName").equalTo("Bobby").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i(TAG, "dataSnapshot value = "+dataSnapshot.getValue());
if(dataSnapshot.hasChildren()){
Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator();
DataSnapshot snap = iter.next();
if(snap.hasChildren() && snap.getValue() instanceof HashMap) {
HashMap map = (HashMap) snap.getValue();
if(map.containsKey("username")) {
Log.i(TAG, "onDataChange: username = " + map.get("username"));
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
EDIT:
The Database structure is looking like this:
{
"Scores" : {
"id1" : {
"fullName" : "Robert",
"score" : 96,
"username" : "rob"
},
"id2" : {
"fullName" : "Michael",
"score" : 87,
"username" : "mike"
},
"id3" : {
"fullName" : "Bobby",
"score" : 150,
"username" : "bob"
}
}
}
Thanks in advance.
SUMMARY:
Using wilkas' answer I came to the following code snippet to get the wanted result:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("Scores");
ref.orderByChild("fullName").equalTo("Bobby").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i(TAG, "dataSnapshot value = "+dataSnapshot.getValue());
if(dataSnapshot.hasChildren()){
Iterator<DataSnapshot> iter = dataSnapshot.getChildren().iterator();
while (iter.hasNext()){
DataSnapshot snap = iter.next();
String nodId = snap.getKey();
String username = (String) snap.child("username").getValue();
//received results
Log.i(TAG, username + " on nod " + nodId);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
It works well when several entries have a fullName equal to 'Bobby'.
Since you add listener under Scores, your childs are id1, id2 and id3. By adding query .orderByChild("fullName").equalTo("Bobby") you filter by subchild and get one result id3. So your first datasnapshot refers to one child id3 (though there could be more children if they would have same name of "Bobby").
In order to get the username, you need to iterate each received child (as you correctly do) - in this case only one child is iterated - and then get child username of that iterated child.
Since you know that every idX contains these children: username, score, fullName. You can easily extract username as follows (in your case snap is reference to child id3):
String username = (String) snap.child("username").getValue();
String fullName = (String) snap.child("fullName").getValue();
long score = (long) snap.child("score").getValue();
Furthermore you can retrieve id too as follows:
String recordId = snap.getKey();
Within the inner iteration you could also get username as follows:
String recordId = snap.getKey();
String username = (String) dataSnapshot.child(recordId).child("username").getValue();
Related
I'm trying to create a PushID from the user's UID in another branch of my database.
So far I have done this:
DatabaseReference userUUID = FirebaseDatabase.getInstance().getReference().child(user.getUid());
String pushUser = userUUID.push().getKey();
HashMap<String, Object> withdrawMap = new HashMap<>();
withdrawMap.put("id", pushUser);
withdrawMap.put("balance", "5000");
withdrawMap.put("email", emailMP);
withdrawMap.put("date", dateString);
withdrawMap.put("statut", "Pending");
withdrawMap.put("image", mediumPackImage);
referenceWithdraw.child(pushUser)
.setValue(withdrawMap)
.addOnCompleteListener(new OnCompleteListener<Void>() {}
Here is my database in .json format(the first and second are from 2 different users)
{
"Withdraw" : {
"-Mn1-FONHwx1-EmwZKND" : {
"amount" : "5000",
"date" : "27/10/2021",
"email" : "example#gmail.com",
"id" : "-Mn1-FONHwx1-EmwZKND",
"statut" : "Pending"
},
"-Mn1-ZI4lkbv4P76UMQl" : {
"amount" : "5000",
"date" : "27/10/2021",
"email" : "example#gmail.com",
"id" : "-Mn1-ZI4lkbv4P76UMQl",
"statut" : "Pending"
}
}
}
referenceWithdraw = FirebaseDatabase.getInstance().getReference().child("Withdraw");
I would like to say that logically the child is an ID created from the Uid of the Firebase user(the code makes it clear in any case)
Now imagine that I want to retrieve users' PushIds and show content
referenceHistory = FirebaseDatabase.getInstance().getReference().child("Withdraw").child("????");
**
I have to put what in the second child to be able to retrieve the pushIDs that are created from the user ID?**
Hoping that I explained myself well
To be able to get the data that corresponds to a single user with a specific email address, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference withdrawRef = rootRef.child("Withdraw");
Query queryByEmail = withdrawRef.orderByChild("email").equalTo("example#gmail.com");
queryByEmail.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot ds : task.getResult().getChildren()) {
String id = ds.child("id").getValue(String.class);
Log.d("TAG", id);
}
} else {
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
According to your comment:
The first one interests me.
Since both children have the same email addresses, then the result in the logcat will be:
-Mn1-FONHwx1-EmwZKND
-Mn1-ZI4lkbv4P76UMQl
If you want only the first result, you either add a .limit(1) call to your existing query, or you make sure you have unique email addresses.
I'm having trouble with snapshot being able to print the values, but being specific by using get values returns null.
I'm trying to retrieve the the list uploaded in Firebase and compare it to the list that the user will pass.
rootReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot item_child : snapshot.getChildren())
{
String recId = item_child.getKey();
DatabaseReference rootReference = FirebaseDatabase.getInstance("https://what-s-cookin-a3bec-default-rtdb.asia-southeast1.firebasedatabase.app/")
.getReference().child("Recipes").child(recId);
Log.d(TAG, "RECID: " + recId);
rootReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren())
{
Log.d(TAG, "SNAPSHOT: " + ds);
Log.d(TAG, "SPECIFIC: " + ds.child("ingredients"));
if(ds.child("ingredients").getValue() != null)
{
Log.d(TAG, "INGREDIENTS NOT NULL");
ArrayList<String> ing = new ArrayList<String>();
for (DataSnapshot ings : snapshot.child("ingredients").getChildren())
{
ing.add(ings.getValue(String.class));
Log.d(TAG, "DS: " + ds);
Log.d(TAG, "INGS: " + ings);
}
This is the result from logcat:
SNAPSHOT: DataSnapshot { key = ingredients, value = {0=Fish, 1=bitter, 2=cilantro} }
SPECIFIC: DataSnapshot { key = ingredients, value = null }
Logcat screenshot
This is our firebase:
Firebase Screenshot
Recipes
1634971267099
favCount: 8
id: "1634971267099"
imageUrl: "https://firebasestorage.googleapis.com/v0/b/wha..."
ingredients
0: "Fish"
1: "bitter"
2: "cilantro"
mainIng: "Pork"
measure: "test"
name: "Pochero"
prod: "test"
serve: "15"
time: "30"
uid: "tMdUFcAelyeVo5DYW3P7HolRW4S2"
Check your code is matching with Firebase data.
It would be more clear if you post screenshot of Firebase data to understand the database hierarchy.
Its difficult to understand the database structure from your code.
Query sqlite = mDatabaseReference.child("Messages").child(MessageSenderId).child(MessageRecieverId);
sqlite.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("Message")) {
String msg = dataSnapshot.child("Message").getValue().toString();
String from = dataSnapshot.child("From").getValue().toString();
String time = dataSnapshot.child("Time").getValue().toString();
} else {
Toast.makeText(getApplicationContext(), "NULLLL", Toast.LENGTH_SHORT).show();
}
Database
This is the most basic thing in the database. I have never got a problem with childEvent or valueEvent and i want a single event for now and I'm not able to fetch.
There is no error because i have put an if statement and it shows toast as null which means dataSnapshot doesn't have a child named messages but it's right there. I tried putting a for loop too, but didn't work
You have not given the full reference. There is a list of push keys and you have to use a foreach loop.
Query sqlite = mDatabaseReference.child("Messages").child(MessageSenderId).child(MessageRecieverId);
sqlite.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot vinSnapshot : dataSnapshot.getChildren()) {
if (vinSnapshot .hasChild("Message")) {
String msg = dataSnapshot.child("Message").getValue().toString();
String from = dataSnapshot.child("From").getValue().toString();
String time = dataSnapshot.child("Time").getValue().toString();
} else {
Toast.makeText(getApplicationContext(), "NULLLL", Toast.LENGTH_SHORT).show();
}
}
Or you can store all data into ArrayList then perform your task.
I have the following Firebase database
lessons :
Id_lesson : "XXX1"
Name_lesson : "Geography"
Date_lesson : "25/09/2018"
Id_lesson : "XXX2"
Name_lesson : "Mathematics"
Date_lesson : "25/09/2018"
Id_lesson : "XXX1"
Name_lesson : "Physics"
Date_lesson : "26/09/2018"
Id_lesson : "XXX2"
Name_lesson : "Biology"
Date_lesson : "26/09/2018"
I need to delete all the lessons entries from a specific date (sharing the same Date_lesson child).
I tried this method :
private void Delete_CR_Lessons(Date date) {
final String date_to_delete_string = DateFormat.getDateInstance(DateFormat.SHORT).format(date);
Log.i("Tag", "date to delete : "+date_to_delete_string);
DatabaseReference drTest = FirebaseDatabase.getInstance().getReference();
drTest.child("lessons").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot:snapshot.getChildren()) {
Log.i("Tag", "iteration for dataSnap");
if(dataSnapshot.hasChild(date_to_delete_string)){
dataSnapshot.getRef().setValue(null);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("TAG: ", databaseError.getMessage());
}
});
During execution of the method (with String date "25/09/2018" for example), the entries are not deleted from Firebase Database. I see the two logs I specified but I also see a log called
"I/chatty: uid=10298(com.example.myname.lessonsmanagment) identical 2 lines"
I suppose that the method doesn't work because it cannot detect both Lessons from date 25/09/2018 (Geography and Mathematics) on the same time.
Does anyone have an idea on how to make it work ?
first of all, you need to query/order the data with the date
you can simply do it using this sample.
mRef.child("lessons").orderByKey().equalTo(Date_lesson)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postsnapshot :dataSnapshot.getChildren()) {
String key = postsnapshot.getKey();
dataSnapshot.getRef().removeValue();
}
});
where mRefis you lessons branch ref
From this I want take the value of email from mailID and subject, title from mailText.i'm able to access the value of single child but when it show null with when try get with all three.
Following code working for single child:
DatabaseReference databaseRef = database.getReference("/");
databaseRef.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<String> email = new ArrayList();
for (DataSnapshot sd: dataSnapshot.getChildren()) {
String emailStr = sd.child("email").getValue(String.class);
email.add(emailStr);
System.out.println(email);
}
latch.countDown();
}
Above code gives me array contain the all email like that i want to take value of email,title and subject.
Assuming that the new node is a direct child of your Firebase root, to achieve what you have explained in your comments, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference newRef = rootRef.child("new");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.child("mailID").getChildren()) {
String email = ds.child("email").getValue(String.class);
String name = ds.child("name").getValue(String.class);
Log.d("TAG", email + " / " + name);
}
for(DataSnapshot ds : dataSnapshot.child("mailText").getChildren()) {
String title = ds.child("title").getValue(String.class);
String subject = ds.child("subject").getValue(String.class);
Log.d("TAG", title + " / " + subject);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
newRef.addListenerForSingleValueEvent(valueEventListener);
As you see, you need to attach a listener one step higher in your tree hierarchy and to loop throught the children using getChildren() method twice.
You need to change the database structure(there is no join in firebase), to be able to query and get the required data:
new
mailId
email: userx#gmail.com
name:userx
title: test title
Body: test body
Then you will be able to retrieve the required data for the user.
You can also use Queries to be able to get the related data, example:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("new");
ref.orderByChild("email").equalTo("userx#gmail.com");