Assume my database has the following structure:
data
|___randomId1
| |_________randomData1
| |______Key1: value
| |______Key2: value
|___randomId2
|_________randomData2
|______Key1: value
|______Key2: value
And I want to iterate to get all values, and also save the parent id (randomId1, randomId2). How can I loop through? right now I have the following:
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
// what to put here to get the values and also save the ids?
}
}
You see that each randomData has the same map (Key1 and Key2).
To solve this, you need use two nested loops like in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference dataRef = rootRef.child("data");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
String parentKey = dSnapshot.getKey();
for(DataSnapshot ds : dSnapshot.getChildren()) {
String key = ds.getKey();
String key1 = ds.child("Key1").getValue(String.class);
String key2 = ds.child("Key2").getValue(String.class);
Log.d(TAG, key1 + " / " + key2);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
dataRef.addListenerForSingleValueEvent(valueEventListener);
Related
What I really need is to show every value in the "Income" field in TextView.
250
105
Is this possible? If it is possible please help me.
This is how I insert values to database
private void addReport() {
Float total_Income = Float.valueOf(tv_total_income.getText().toString());
String current_date = tv_current_date.getText().toString();
SimpleDateFormat sdf = new SimpleDateFormat("MMMM");
String currentDateandTime = sdf.format(new Date());
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference mDbRef = mDatabase.getReference("Reports"+"/"+currentDateandTime+"/"+current_date).child("Date");
mDbRef.setValue(current_date);
DatabaseReference mDbRef1 = mDatabase.getReference("Reports"+"/"+currentDateandTime+"/"+current_date).child("Income");
mDbRef1.setValue(total_Income);
}
While Sairaj Sawant's answer might work, keep in mind that there is no need to attach a listener at every iteration of the loop. A more convenient solution is to attach a listener only once, like in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference juneRef = rootRef.child("Reports").child("June");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String totalIncome = "";
for(DataSnapshot ds : dataSnapshot.getChildren()) {
totalIncome = totalIncome + ds.child("Income").getValue(String.class) + " ";
}
Log.d("TAG", totalIncome);
textView.setText(totalIncome);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
juneRef.addListenerForSingleValueEvent(valueEventListener);
This code will work only if the Income property is of type String, as it is set in your 20-06-2020 child. However, the above code will not work if the value is set as an Integer as it set in your second 21-06-2020 child. Remember, both types of values must match. You either set both as String and the above code will work, or you set them as numbers, case in which you should use this line:
totalIncome = totalIncome + ds.child("Income").getValue(Long.class) + " ";
Try accessing the children of June under Reports and looping through to get income as below :
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference reportsRef = rootRef.child("Reports").child("June");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String key = ds.getKey();
DatabaseReference keyRef = rootRef.child(key).child("income");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds1 : dataSnapshot.getChildren()) {
String income = ds1.getValue(String.class);
Log.d("TAG", income);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
keyRef.addListenerForSingleValueEvent(valueEventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
reportsRef.addListenerForSingleValueEvent(eventListener);
I'm trying to get these values in the node panadol and profinal. but it's not working.
I was able to get the date successfully. Here's my code
for(final String id: MedicinesListActivity.orderIdsList){
//get the date of the order
DatabaseReference dateReference = FirebaseDatabase.getInstance()
.getReference("Orders").child(id);
dateReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//date
String date = dataSnapshot.child("date").getValue(String.class);
Log.i("Date", date);
//loop through all the products in the specific order id
for(DataSnapshot s : dataSnapshot.child(MedicinesListActivity.userId).child("panadol").getChildren()){
Order order = s.getValue(Order.class);
Log.i("Item_Name", ""+ order.getName());
}
}
});
}
MedicineListActivity.orderIds -> contains all the orderIds i want to loop through
and the class Order contains the name and the orderQuantity.
But it's not working.
To solve this, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("Orders").child(id).child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
String orderQuantity = ds.child("orderQuantity").getValue(String.class);
Log.d("TAG", name + "/" + orderQuantity);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
The output in the logcat will be:
panadol/3.0
profinal/2.0
Or using the Order class:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("Orders").child(id).child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Order order = ds.getValue(Order.class);
Log.d("TAG", ds.getName() + "/" + ds.getOrderQuantity);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
The result will be the same.
In both cases, you have to use all node names in your reference to be able to display that data.
It seems like under each user's node, you have a list of named products (panadol, profinal). Your code looks up one named product panadol in that list with dataSnapshot.child(MedicinesListActivity.userId).child("panadol"):
//loop through all the products in the specific order id
for(DataSnapshot s : dataSnapshot.child(MedicinesListActivity.userId).child("panadol").getChildren()){
Order order = s.getValue(Order.class);
Log.i("Item_Name", ""+ order.getName());
}
Since you then iterate over the child nodes of panadol, your s snapshot refers to the individual properties of panadol: name and orderQuantity. But your code seems to try to map each of those properties to an entire Order object, which won't work.
You have two options:
Show the individual properties, without using the Order class:
for(DataSnapshot propSnapshot: dataSnapshot.child(MedicinesListActivity.userId).child("panadol").getChildren()){
Log.i("Item_Name", propSnapshot.getKey() + "="+ propSnapshot.getValue());
}
Don't use the loop, and get the products and their properties in an Order object:
for(DataSnapshot propSnapshot: dataSnapshot.child(MedicinesListActivity.userId).getChildren()){
Order order = s.getValue(Order.class);
Log.i("Item_Name", propSnapshot.getKey() + "="+ propSnapshot.getValue());
}
I am trying to retrieve an url from Firebase in Android. However, my problem is that I can't retrieve the url without also getting the unique key of the child.
The value I am trying to retrieve is the following:
Down below is the code I use to retrieve the data from firebase.
final FirebaseDatabase database = FirebaseDatabase.getInstance();
myRef = database.getReference().child("LoadItems");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot child : dataSnapshot.getChildren() ){
String key;
key = child.getKey();
Log.d(TAG, "onDataChange: " + key);
Log.d(TAG, "onDataChange: " + child.getValue());
}
}
#Override
public void onCancelled(DatabaseError databaseError) { }
});
So what I am trying to get is what the url alone.
There is no need to know any key in order to get that URL. So please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference shoesRef = rootRef.child("LoadItems").child("Shoes");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String url = ds.getValue(String.class);
Log.d(TAG, url);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
shoesRef.addListenerForSingleValueEvent(valueEventListener);
I have two nodes Users and Plants
Users
|
|-plantId
|
|-image
|
|-imageLink
|-plantId
|
|-image
|
|-imageLink
Plants
|-plantId
|
|-collectedPlant
|
|-plantCount
The plantid in users and plants will be same. I need to get a HashMap containing plant id-imagelink and plantCount.
I have the two nodes data separately with me. Is there a simple way to solve it?
To solve this according to the edited database structure and assuming that the plantCount property is defined as a Long, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference imageRef = rootRef.child("Users").child("plantId").child("image");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String imageLink = ds.child("imageLink").getValue(String.class);
DatabaseReference collectedPlantRef = rootRef.child("Plants").child("plantId").child("collectedPlant");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Long> map = new HashMap<>();
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
Long plantCount = dSnapshot.child("plantCount").getValue(Long.class);
map.put(imageLink, plantCount);
}
//Do what you want with this Map.
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
collectedPlantRef.addListenerForSingleValueEvent(eventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
imageRef.addListenerForSingleValueEvent(valueEventListener);
As you can see, I have used nested queries in order to get the Map that you are looking for.
I am trying to turn a DataSnapshot object to HashMap then iterate it for accessing latitude longitude and avatar values for each player. Because after this i will use those values to render markers on map.
db
Another question is is it possible to exclude users itself from the query ?
I mean is it possible to write mydb.child("map").child("players").notequalto(username).addValueEventList...
Or do i have to exclude it with code after pulling the data?
mydb.child("map").child("players").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
HashMap<String,Object> players= new HashMap();
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
players.put(childSnapshot.getKey(), childSnapshot.getValue());
}
Log.d("players",dataSnapshot.getValue().toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
output:
D/players: {lifesuxtr={lat=40.8901741, long=29.3772963, avatar =petyr}, lastpeony={lat=40.89, long=29.37, avatar=dino}}
Assuming that the map node is a direct child of your Firebase database root, to get those values, please the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference playersRef = rootRef.child("map").child("players");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<Double, Double> players = new HashMap<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
double lat = ds.child("lat").getValue(Double.class);
double long = ds.child("long").getValue(Double.class);
Log.d("TAG", lat + " / " + long);
players.put(lat, long);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
playersRef.addListenerForSingleValueEvent(eventListener);
The output will be:
40.89 / 29.37
40.89 / 29.37
Having there values, you can now add your markers. And answering to your question, no, you cannot use negation in a query. There is no notEqualTo() method in Firebase.