So I have a list of objects stored in firebase and want to query for just one object using child equal to method but I am getting a map with single key value instead.
Code below showing what I want to achieve instead of dealing with hashmaps.
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference coutryRef = database.getReference(FireContract.PATH_COUNTRY);
Query countryQuery = coutryRef.orderByChild(FireContract.CHILD_NAME)
.equalTo(TestUtilities.TEST_COUNTRY_ALGERIA).limitToFirst(1);
countryQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Country country = dataSnapshot.getValue(Country.class);
assertEquals(TestUtilities.TEST_COUNTRY_ALGERIA, country.getName());
//get country key
String coutryKey = dataSnapshot.getKey();
}
#Override
public void onCancelled(DatabaseError databaseError) {
fail("Failed to get country: " + databaseError.getMessage());
}
});
When you fire a query, you will always get a list of results. Even when there is only a single item matching the query, the result will be a list of one item.
To handle the list, you can either use a ChildEvenListener or you can loop over the children in your ValueEventListener:
countryQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot countrySnapshot: dataSnapshot.getChildren()) {
Country country = countrySnapshot.getValue(Country.class);
assertEquals(TestUtilities.TEST_COUNTRY_ALGERIA, country.getName());
//get country key
String countryKey = countrySnapshot.getKey();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
fail("Failed to get country: " + databaseError.getMessage());
}
});
Related
I am developing an android application and now I am stuck in retrieving data from particular nodes like I want to retrieve only one value from each nodes. The database structure shows below.
How can I retrieve the second unique id that created by Firebase database?
First create a POJO class to get the values you want, it should be writen the same way as you have them in Firebase.
public class AppointmentsPojo {
private String appointmentStuts;
public AppointmentsPojo(){
}
public String getAppointmentStuts() {
return appointmentStuts;
}
public void setAppointmentStuts(String appointmentStuts) {
this.appointmentStuts = appointmentStuts;
}
}
Then just loop inside Appointments to get each appointmentStuts
mDatabase.child("Appointments").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Looping inside Appointments to get each appointmentsStuts
for(DataSnapshot snapshot: dataSnapshot.getChildren()){
AppointmentsPojo ap = snapshot.getValue(AppointmentsPojo.class);
//Getting each appointmentStuts
String appointmentStuts = ap.getAppointmentStuts();
//To get each father of those appointments
String key = snapshot.getKey();
Log.e("Data: " , "" + appointmentStuts );
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
Where mDatabase is
DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference();
To get the value of appointmentStuts only from the first object, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Appointments").child(PostKey).limitToFirst(1);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String appointmentStuts = ds.child("appointmentStuts").getValue(String.class);
Log.d(TAG, appointmentStuts);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
query.addListenerForSingleValueEvent(valueEventListener);
I want to get data according to user's ranking. First order by user's points and get users position in node. But I can't think of the way to implement this.
First This is my firebase 'users' node
Maybe It will be like 'databaseRef.child("users").orderByChild("points")...'
I don't know from here.
ps. It's not get nth item. It's 'where is the item' ( item's nth )
Thank you!
This can be done by adding a ctr in you dataSnapshot loop
myRef = FirebaseDatabase.getInstance().getReference().child("users");
final Query query = myRef.orderByChild("points");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int total = dataSnapshot.getChildrenCount();
int i = 0;
// loop through dataSnapshot
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
String nickName = childSnapshot.child("nickName").getValue(String.class);
if (nickName.equals(mUser.getNickName()) {
//when nickName would match
int userPlace = total - i;
int points = childSnapshot.child("points").getValue(Interger.class);
//do something here
break;
} else {
i++;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Kindly read
Retrieving Data.
How Data is Ordered
The callback function receives a DataSnapshot, which is a snapshot of
the data. A snapshot is a picture of the data at a particular database
reference at a single point in time. Calling val() / getValue() on a
snapshot returns the a language-specific object representation of the
data. If no data exists at the reference's location, the snapshot's
value is null.
If you want to get all points then check this LOGIC.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("products");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<Integer> points = new ArrayList<>();
for (Map.Entry<String, Object> entry : products.entrySet()){
Map singleUser = (Map) entry.getValue();
points.add((Integer) singleUser.get("points"));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
I solve this problem. Android_K.Doe's answer is right. I add some code in his code. Because Firebase database does not give descending query.
final Query query = databaseReference.child("users").orderByChild("points");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int i = 0;
int all = (int) dataSnapshot.getChildrenCount();
Log.d(TAG, "all: " + all);
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String nickName = ds.child("nickName").getValue(String.class);
if (nickName.equals(user.getNickName())) {
Log.d(TAG, "nickName: " + user.getNickName());
int userPlace = i;
Log.d(TAG, "position: " + userPlace);
myInfoRankingNumTxt.setText(Integer.toString(all - (i)) + "위");
break;
} else {
i++;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I have a list of objects on my Firebase database, and the key for each object is a timestamp. I can get the last one using limitToLast(1), and the data snapshot I get is:
{ key = time_stamps, value = {1510768441759={id=f454445c6e880df31e, coordinates={latitude=-4.1461734, longitude=20.5992437}}} }
Where 1510768441759 is the timestamp.
How do I read the coordinates? I've tried to convert the value to a POJO, but I cannot, because the timestamp is unknown to me, and in a POJO it would be the name of a property…
Thanks.
If you do it without a parent POJO but only with coordinates pojo you can just do the following by the datasnapshot:
Query query = ref.child("time_stamps").orderByKey();
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot item: dataSnapshot.getChildren()){
if (!dataSnapshot.hasChildren()) {
return;
}
for(DataSnapshot childSnapShot :item.getChildren()){
final String timestamp = childSnapShot.getKey();
final DataSnapshot parentSnapShot = childSnapShot.child(timestamp);
if (!parentSnapShot.hasChildren()) {
continue;
}
Double latitude = parentSnapShot.child("latitude").getValue(Double.class);
Double longitude = parentSnapShot.child("longitude").getValue(Double.class);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
etc.
You have:
time_stamp
1510768441759
id: f454445c6e880df31e
coordinates
latitude=-4.1461734
longitude=20.5992437
try this, assuming you do not have this 1510768441759 :
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("time_stamp");
Query query = reference.orderByChild("id").equalTo(f454445c6e880df31e );
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot datas: dataSnapshot.getChildren()){
String keys=datas.getKey();
for(DataSnaphot ds :datas.getChildren()){
String latitudes=ds.child("latitude").getValue().toString();
String longitudes=ds.child("longitudes").getValue().toString();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The above is done assuming you are on this datasnasphot time_stamp. First you do a query to be able to get the coordinates of this id: f454445c6e880df31e. Then since you are on this datasnasphot time_stamp, you have to loop once to be able to retrieve this 1510768441759, then loop again to be able to get the latitude and the longitude.
I want to search a condition ,if student studied at 'swe' department then i will show name and id for every student who are studied at swe department.
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("user");
databaseReference.orderByChild("department").equalTo("swe").addValueEventListener(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
String str = dataSnapshot.child("department").getValue(String.class);
Toast.makeText(MainActivity.this,str,Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
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.
Your current code fails to handle the fact that the result is a list. To solve this, loop over dataSnapshot.getChildren():
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("user");
databaseReference.orderByChild("department").equalTo("swe").addValueEventListener(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String str = dataSnapshot.child("department").getValue(String.class);
Toast.makeText(MainActivity.this,str,Toast.LENGTH_LONG).show();
}
}
Here member’s key in Group is User’s key.
Task: Want to fetch comida_id froenter code herem User based on Group’s member key.
Here we are trying to first fetch member keys from Group. While fetching member key we also want to fetch User and User’s comida_id while that member’s loop is going. So the scenario will be First we are going to fetch all keys from Group based on Group’s key ( for example createTime, groupName, members ). Now from that we will execute loop on members so will get member’s key. Now while fetching this member’s key in that loop, we want to fetch comida_id from User’s, which will be fetch in that loop only.
GroupKey -> get Data(createTime, groupName, members, restaurants) -> fetch members key and comida_id ( in Loop (get member key then fetch comida_id ))
*My Code
FirebaseDatabase mDatabase_gp = FirebaseDatabase.getInstance();
mDatabase_gp.getReference("Group/"+group_key).addValueEventListener(
new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Map<String, Object> valuesMap = (HashMap<String, Object>) dataSnapshot.getValue();
Map userkey = (Map) valuesMap.get("members");
Log.d("Members", String.valueOf(userkey));
for (Object ke: userkey.keySet())
{
Log.d("runfirst","First Run");
String key = String.valueOf(ke.toString());
Log.d("Member key",key);
// HERE WHAT CORRESPONDS TO JOIN
FirebaseDatabase User = FirebaseDatabase.getInstance();
User.getReference("User/"+key).addValueEventListener(
new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Map<String, Object> valuesMap = (HashMap<String, Object>) dataSnapshot.getValue();
String userid = String.valueOf(valuesMap.get("comida_id"));
Log.d("comida_id",userid);
Toast.makeText(ChatSectionActivity.this,userid,Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
}
);
}
Log.d("runlast","Last Run");
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
}
);
*
In Above code we tried to achieve same thing but here this code will fetch all member keys from group first. After fetching all members it will fetch comida_ids in another loop.. So there will be like two different loops working to fetch comida_id from members. It’s not working like join query.
GroupKey -> get Data(createTime, groupName, members, restaurants) -> fetch members key (in Loop (get member key) after then fetch comida_id .
*1) I was try this solution - How to perform join query in Firebase?
**But get this error –
Incompatible types.
Required: com.google.firebase.database.DatabaseReference
Found: com.google.firebase.database.ValueEventListener
https://i.stack.imgur.com/ljlWo.png
Firebase doesn't have join queries. And what you are doing wrong is your are referencing your data base on Fireabaseuser, which is wrong.
mdatabaseReference.child("Answer").child("Answer"+QID).orderByChild("questionId").equalTo(QID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (muftiAnswer_List.size() > 0)
muftiAnswer_List.clear();
for (DataSnapshot postsnapshot : dataSnapshot.getChildren()) {
final AnswerClass muftiAnswer = postsnapshot.getValue(AnswerClass.class);
String ide=muftiAnswer.getMuftiId(); //getting AlimId From Class object
Log.e(TAG, "Alim:"+ muftiAnswer.getMuftiId());
//Using Query to get Alim Name From Data Table.!
mdatabaseReference.child("users").child("Alim").child(ide).addListenerForSingleValueEvent(new ValueEventListener() {
#Override //.orderByChild("alimId").equalTo(user_Id)
public void onDataChange(DataSnapshot dataSnapshot) {
Log.e(TAG, "AlimNode:");
for(DataSnapshot postSnapshot:dataSnapshot.getChildren())
{
Log.e(TAG, "EqualNode:");
if(postSnapshot.getKey().equals("alimName"))
{
Log.e(TAG, "AlimNameNodeSnapShot:");
//Setting Alim Name in Current Object replcing id for name
muftiAnswer.setMuftiId(postSnapshot.getValue().toString());
}
// resultMuftiAnswer_List.add(muftiAnswer);
}//End of snapshot
}//ondata Change
#Override
public void onCancelled(DatabaseError databaseError) {
// Failed to read value
Log.w(TAG, "Failed to read value.", databaseError.toException());
}
});//End OF Alim Query
}//end of comments
circular_progress2.setVisibility(View.GONE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(Details_Activity.this, "LOLOLOL", Toast.LENGTH_SHORT).show();
}
});
You have to use nested loops for doing joins like MYSQL
Query query = reference.child("issue").orderByChild("id").equalTo(0);
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 issue : dataSnapshot.getChildren()) {
// do something with the individual "issues"
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Visit link for better understanding
https://firebase.googleblog.com/2013/10/queries-part-1-common-sql-queries.html