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.
Related
Everything is working fine, I think just userDataModel.setUserRating(aFloat / (int) dataSnapshot.getChildrenCount()); is not giving value.
And String.valueof(aFloat / (int) dataSnapshot.getChildrenCount()));
Is also giving the correct value.
FirebaseDatabase.getInstance().getReference().child("Users").child(userDataModel.getUserID()).child("Ratings")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
userDataModel1 = dataSnapshot.getValue(UserDataModel.class);
aFloat = aFloat + Float.parseFloat(Objects.requireNonNull(dataSnapshot1.getValue()).toString());
}
userDataModel.setUserRating(aFloat / (int) dataSnapshot.getChildrenCount());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
UserDataModel
public class UserDataModel {
float userRating;
public float getUserRating() {
return userRating;
}
public void setUserRating(float userRating) {
this.userRating = userRating;
}
}
Image URL: https://i.stack.imgur.com/t14Cc.png
This is happening maybe because userDataModel.setUserRating(aFloat / (int) dataSnapshot.getChildrenCount()); is returning null so you don't get a value
The problem in your code us the fact that your UserDataModel has a field named userRating, while in your database the property is actually a uid. This property is dynamic, so you cannot use a POJO class for that. If you want to get the values of those ratings, please try this:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ratingsRef = rootRef.child("Users").child(uid).child("Ratings");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
double rating = ds.getValue(Double.class);
Log.d("TAG", "rating: " + rating);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
ratingsRef.addListenerForSingleValueEvent(valueEventListener);
The output in the logcat will be values of all ratings that exist within the Ratings node.
3.5
2
Now, you can simply make the average or whatever you need with those values.
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 looking for a way to get data from the firebase real-time database in a format like an array[] or a String.
My database looks like this:
Link to image of database
Or:
Database
|
-->Users
|
-->UID1
-->UID2
This is at the root of the database
I want to get a list of all of the UIDs in the "Users" child.
This is the code I have so far and am a bit stuck on:
DatabaseReference databaseReference = firebaseDatabase.getReference("Users");
databaseReference.addValueEventListener(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String UIDs = dataSnapshot.getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I am a bit of a rookie as it comes to java, android studio, and firebase. I am trying to get the data in a format I know how to use like a String or an Array[] of Strings. I looked around if other people had maybe asked the same question, but I could get the answers to those questions to work/didn't understand them.
Thanks in advance for your time!
To get the a list of uids, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("Users");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> list = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String uid = ds.getKey();
list.add(uid);
}
//Do what you need to do with your list
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
usersRef.addListenerForSingleValueEvent(valueEventListener);
I recommend you to use the list only inside the callback otherwise it will be empty. If you want to use it outside the onDataChange() method, I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.
For your above question I will give both ways: ArrayList or String with delimiters
ArrayList<String> uids = new ArrayList<String>();
FirebaseDatabase.getInstance().getReference("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for(DataSnapshot snapshot : dataSnapshot.getChildren()) {
uids.add(snapshot.getKey());
}
}
}
#Override
public void onCancelled(DatabaseError error) {
}
});
For String
String uids = "";
FirebaseDatabase.getInstance().getReference("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for(DataSnapshot snapshot : dataSnapshot.getChildren()) {
uids += snapshot.getKey() + ",";
}
}
}
#Override
public void onCancelled(DatabaseError error) {
}
});
This gives an output such as: uid1,uid2,uid3,.....uidn,
You can try this:
DatabaseReference ref=
FirebaseDatabase.getInstance().getReference("Users");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
int i = 0;
for(DataSnapshot d : dataSnapshot.getChildren()) {
name[i] = d.getKey();
i++;
}
}
}//onDataChange
#Override
public void onCancelled(DatabaseError error) {
}//onCancelled
});
name[] is an array of strings!
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);
I want to retrieve data for a specific child, how I can write the code? I try a lot, but it did not work:"([ like in my database here how to get the tasks for specific child like lubna and gets all it's child?
Initialize class variables:
private DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference();
private DatabaseReference lubnaRef = mDatabase.child("tasks/Lubna");
And then for testing purposes I am assuming you are calling this in your onCreate method of your activity, you'd add the following assuming you do not have a data model for it:
lubnaRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//These are all of your children.
Map<String, Object> lubna = (Map<String, Object>) dataSnapshot.getValue();
for (String childKey: lubna.keySet()) {
//childKey is your "-LQka.. and so on"
//Your current object holds all the variables in your picture.
Map<String, Object> currentLubnaObject = (Map<String, Object>) lubna.get(childKey);
//You can access each variable like so: String variableName = (String) currentLubnaObject.get("INSERT_VARIABLE_HERE"); //data, description, taskid, time, title
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
To solve this, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference lubnaRef = rootRef.child("tasks").child("Lubna");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String title = ds.child("title").getValue(String.class);
Log.d(TAG, title);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
lubnaRef.addListenerForSingleValueEvent(valueEventListener);
In the same way you get the title, you can also get the other values. The output in your logcat will be:
Homework
//and so on