Firebase retrieve Data from child by key - java

Now what I am trying to do is to get all the children having category value of shop
I have tried this code
Firebase ref = new Firebase("https://top-africa.firebaseio.com/businesses/);
ref.orderByChild("category").equalTo("shop");
ref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Object ob = dataSnapshot.getValue();
System.out.println("There are " + dataSnapshot.getKey() + " blog posts==" + dataSnapshot.getValue());
}
});
but when I look at the log it printed out all 10 children whereas I suppose I would retrieve only one because there was only one value for category shop.
I don't know what I am missing. Could you please help me to solve the issue?

your reference is pointing to bussiness, so use query to fetch the data with condition
Query mQuery = ref.orderByChild("category").equalTo("Shop");
mQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Object ob = dataSnapshot.getValue();
System.out.println("There are " + dataSnapshot.getKey() + " blog posts==" + dataSnapshot.getValue());
}
});

Related

Springboot + ReactJS + Firebase's Realtime Database

Back-end: Springboot
Front-end: ReactJS
CloudRepo: Firebase Realtime Database
I have a Springboot application that GETs data from the Firebase Realtime Database.
This data is then served via a GET request from reactJS.
I get the JSON object in reactJS as :
What I am trying to do is to map the firebase snapshot to a Java Collection. Here is What I have done so far:
DatabaseReference ref = FirebaseService.getFirebaseDatabase().getReference("/devices/device1");
ref.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
DeviceData message = messageSnapshot.getValue(DeviceData.class);
System.out.println(message);
}
Map<String, DeviceData> document = (Map<String, DeviceData>) dataSnapshot.getValue();
setUpdatedDocumentData(document);
}
public void onCancelled(DatabaseError error) {
System.out.print("-----Error-----:\n" + error.getMessage());
}
});
My POJO looks like this:
public class DeviceData {
String sensor_1;
String sensor_2;
public DeviceData() {}
public DeviceData(String sensor_1, String sensor_2) {
this.sensor_1 = sensor_1;
this.sensor_2 = sensor_2;
}
public String getSensor_1() {
return sensor_1;
}
public void setSensor_1(String sensor_1) {
this.sensor_1 = sensor_1;
}
public String getSensor_2() {
return sensor_2;
}
public void setSensor_2(String sensor_2) {
this.sensor_2 = sensor_2;
}
#Override
public String toString() {
return "DeviceData{" +
"sensor_1='" + sensor_1 + '\'' +
", sensor_2='" + sensor_2 + '\'' +
'}';
}
}
I am getting null in my sensor_1 and sensor_2 log. How can I map the above firebase structure to a collection?
Under each /devices/$device node, you have two nested levels:
For the date
For the time.
Your code only has once loop over the children of the device node, so your messageSnapshot variable is actually a snapshot with all data for all timestamps for a specific date.
To handle your structure correctly, you need two nested loops:
DatabaseReference ref = FirebaseService.getFirebaseDatabase().getReference("/devices/device1");
ref.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dateSnapshot: dataSnapshot.getChildren()) {
for (DataSnapshot timeSnapshot: dataSnapshot.getChildren()) {
DeviceData message = timeSnapshot.getValue(DeviceData.class);
System.out.println(message);
}
}
Map<String, DeviceData> document = (Map<String, DeviceData>) dataSnapshot.getValue();
setUpdatedDocumentData(document);
}
public void onCancelled(DatabaseError error) {
System.out.print("-----Error-----:\n" + error.getMessage());
}
});
If you only care about the latest timestamp on the latest date, you can reduce the amount of data you read from the database by only getting the latest date:
DatabaseReference ref = FirebaseService.getFirebaseDatabase().getReference("/devices/device1");
ref.orderByKey().limitToLast(1).addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dateSnapshot: dataSnapshot.getChildren()) {
for (DataSnapshot timeSnapshot: dataSnapshot.getChildren()) {
DeviceData message = timeSnapshot.getValue(DeviceData.class);
System.out.println(message);
}
}
Map<String, DeviceData> document = (Map<String, DeviceData>) dataSnapshot.getValue();
setUpdatedDocumentData(document);
}
public void onCancelled(DatabaseError error) {
System.out.print("-----Error-----:\n" + error.getMessage());
}
});
You'll still have to read all timestamps for that date, but at least you're now only reading data for the most recent day.

Firebase data retrieve with random keys

I have a firebase data structure for my android app and I want to retrieve the data from random keys generated by push() method which is child of Forum node which is a child of root of the database. Please suggest me a way to do this. Thanks.
To display the values of all the children under Forums node, please use the following lines of code:
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference forumsRef = db.child("Forums");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
String ques = ds.child("ques").getValue(String.class);
String title = ds.child("title").getValue(String.class);
String uid = ds.child("uid").getValue(String.class);
Log.d("TAG", name + " / " + ques + " / " + title + " / " + uid);
}
}
#Override
public void onCancelled(DatabaseError error) {
Log.d("TAG", error.getMessage()); //Never ignore potential errors!
}
};
forumsRef.addListenerForSingleValueEvent(valueEventListener);
You can get all of the children nodes of the parent "Forum" node. Just use getChildren() method. Then just randomly select one of the child node at position index.
DataSnapshot snapshot = dataSnapshot.child("Forums");
Iterable<DataSnapshot> children = snapshot.getChildren();
for (DataSnapshot child: children) {
Object obj = child.getValue(Object.class);
}
first you should write your class model "FormusModel" to store the data from server
you can use this
> >
rootRef.child("Forums").addChildEventListener(new
> ChildEventListener() {
> > #Override
> > public void onChildAdded(DataSnapshot dataSnapshot, String s) {
> > ForumsModel model = dataSnapshot.getValue(FormusModel.class);
//now you can use model.getname();....
> }
Note: you must implemnt another method like onChildCahnge listener

Getting a child's name as well as the value in Firebase Database

In my Firebase Database I have data laid out as such:
paidRecord[
John Smith: UNPAID
Bill Smith: PAID
Mary Smith: UNPAID
]
I am trying to create a String in my app that will display the paid status of all the people. At the moment all I have is a String that displays "UNPAID PAID UNPAID" but what I need is to display the users names as well.
Here is the function:
private void checkPaidStatus(){
paidString = "";
FirebaseDatabase.getInstance().getReference("Flats").child(flatID).child("Bills").child(itemSelected).child("paidRecord").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot != null){
Iterator<DataSnapshot> iterable = dataSnapshot.getChildren().iterator();
//this is the bit that needs to be changed to return properly xd good luck
for (Iterator<DataSnapshot> it = iterable; it.hasNext();){
DataSnapshot dataSnapshot1 = it.next();
paidString = paidString + "new" + dataSnapshot1.getValue(String.class);
textViewPaidStatus.setText(paidString);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
So, is there a way on Firebase Database to return not only the value assigned to a key, but the key itself as well?
Actually, your key is also available in your sub-DataSnapshot just you need to get like bellow
DataSnapshot dataSnapshot1 = it.next();
paidString = paidString + "new" + dataSnapshot1.getValue(String.class);
textViewPaidStatus.setText(paidString);
String mStrkey=dataSnapshot1.getKey()

How to query firebase database to return a value's key's parent's parent?

I am developing a team chat application . I am storing chat data in firebase.
This is my Data structure
The chats are stored under a node named chats.
each immediate child of chats is the name of a team(like whatsapp.. chat groups).
the team node have all chat messages. the chat messages are stored
with a parent node in the format timestamp_chat
My Problem
Now I have to create a firebase query to fetch this team nodes by from key.
That is
if a from: field contains the a given search value (say, "ragesh"), then the parent node "team_name" have to be returned(say,"teamrova") as a datasnapshot.
Simply speaking , I want datasnapshot of teams that have a particular username in the from field.
My Work
I tried the follwing code :
reference1 = FirebaseDatabase.getInstance().getReference().child("chats");
Query chatQuery = reference1.orderByChild("from").equalTo("ragesh");
System.out.println("Chat list :: starting");
chatQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
System.out.println("Chat list :: onChildAdded");
for (DataSnapshot chat : dataSnapshot.getChildren()) {
HashMap<String, Object> hashMap = (HashMap<String, Object>) dataSnapshot.getValue();
System.out.println("Chat list :: The chat group is =>" + dataSnapshot.getKey());
System.out.println("Chat list :: The key & Value => " + chat.getKey() +" :: "+chat.getValue().toString());
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ChatListActivity.this, "Connection Error "+databaseError.getDetails(), Toast.LENGTH_SHORT).show();
System.out.println("Chat list :: databaseError "+databaseError.toString());
}
});
Sadly , above code don't return any value. even the
System.out.println("Chat list :: onChildAdded"); not called. And it
doesn't calls onCancelled also.(so,no error).
I get sturcked by this. please help me.
To get the username:
mRootRef.child("chats").child("teamrova").orderByChild("from").equalTo("ragesh").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot datas: dataSnapshot.getChildren()){
String name=datas.child("from").getValue().toString();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Since you are using addChildeventListener then you do not need the for loop to be able to get those values for (DataSnapshot chat : dataSnapshot.getChildren()) {
You also need to change this:
reference1 = FirebaseDatabase.getInstance().getReference().child("chats");
to this:
reference1 = FirebaseDatabase.getInstance().getReference().child("chats").child("teamrova");
The above code is an alternative with addValueEventListener

Firebase OrderbyChild Query returns the parent key

I am having a problem retrieve and delete the correct level of the node in Firebase database using the orderByChild().equalTo() method.
Searched over the web for quite a while and didn't really solve my problem. Please help.
My database structure:
My Firebase methods to add and delete photo
private void addPhotoToDatabase(String url){
Log.d(TAG, "addPhotoToDatabase: adding photo to database");
String newPhotoKey = myRef.child(mContext.getString(R.string.dbname_user_photos)).push().getKey();
Photo photo = new Photo();
photo.setDate_created(getTimeStamped());
photo.setImage_path(url);
photo.setUser_id(FirebaseAuth.getInstance().getCurrentUser().getUid());
photo.setPhoto_id(newPhotoKey);
//insert into database.
myRef.child(mContext.getString(R.string.dbname_user_photos)).child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child(newPhotoKey).setValue(photo);
}
private void deletePhotoFromDatabase(String image_path){
Log.d(TAG, "deletePhotoFromDatabase: deleting photo from database");
Log.d(TAG, "deletePhotoFromDatabase: image_path is " + image_path);
String user_id = FirebaseAuth.getInstance().getCurrentUser().getUid();
myRef.child(mContext.getString(R.string.dbname_user_photos))
.child(user_id)
.orderByValue().equalTo(image_path).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String photoKey = dataSnapshot.getKey();
Log.d(TAG, "onDataChange: photo key is " + photoKey);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
I know I don't have a removeValue or setValue(null) method yet because I just can't get to the correct level. The photoKey I was trying to retrieve is the -L-FnLvNxLauiue4InSxE which was automatically generated when adding into Firebase. However, the log always returns to its parent node which is the UID.
By the way, the image_path I retrieved from the Firebase storage which was logged correctly.
Could someone give me some inspirations where I did wrong? Thanks a lot!
change this:
myRef.child(mContext.getString(R.string.dbname_user_photos))
.child(user_id)
.orderByValue().equalTo(image_path)
to this:
DatabaseReference myRef=FirebaseDatabase.getInstance().getReference();
myRef.child("user_photos").child(user_id).orderByChild("photo_id").equalTo(image_path);
Im assuming user_photos is a direct child under root, thus using the above myRef
Edit:
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot data : dataSnaphot.getChildren()){
String photoKey = data.getKey();
Log.d(TAG, "onDataChange: photo key is " + photoKey);
} }

Categories