Changing firebase data according to query - java

Code
Query mSeenRef = mDatabaseReference.child("Messages").child(MessageRecieverId).child(MessageSenderId).orderByChild("From").equalTo(MessageRecieverId);
This is the query and I want to change another child if this query is true... Like similar to adding value event listener and fetching this above querys data... just that instead of fetching i want to change data but I cant use setValue method inside value event listener so what should I do?
I also have UIDS inside MessageRecieverId and inside that is From

Try the following:
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
Query mSeenRef = db.child("Messages").child(MessageRecieverId).child(MessageSenderId).orderByChild("From").equalTo(MessageRecieverId);
mSeenRef.addValueEventListener(new ValueEventListener(){
#Override
public void onDataChange(DataSnapshot dataSnapshot){
if(dataSnapshot.exist()) {
for(DataSnapshot ds: dataSnapshot.getChildren()){
String keyId=ds.getKey();
DatabaseReference ref= db.child("Messages").child(MessageRecieverId).child(MessageSenderId).child(keyId);
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("Seen", true);
ref.updateChildren(childUpdates);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
This will check if the query exists in the database using dataSnapshot.exists(), then if this query exists, you will be able to change the value of a child. You need to use the method updateChildren() to update only one attribute.
Check here for more information:
https://firebase.google.com/docs/database/android/read-and-write#update_specific_fields

Related

Firebase RealTime Database querying with multiple selected field values in Android not working

Trying to query the data from RealTime Database based on selected values, but multiple inputs as Arraylist are not working in a single query.
private void readUsers()
{
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
reference.getRoot().equals(query);
Query query12 = reference.child("Users").equals("g#gmail.com");//**how to add multiple email id or as array list**
query12.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
for (DataSnapshot issue : dataSnapshot.getChildren())
{
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Kindly help me.
You cannot add multiple conditions to the following query:
Query query12 = reference.child("Users").equals("g#gmail.com");
The orderBy() and equalTo() methods can be used in a query only once. You can use a range, or why not, Cloud Firestore as explained in my answer from the following post:
Firebase multiple queries in android

How to retrive the push key value and update child values of key value

Hello Everyone
I am using push method to add data on my realtime Firebase database. Now I would like to retrive sellername and update the new sellername from app and save changes in Firebase database as well.
How can I do that?
I'm using below code but I"m getting different key value each time randomly
instead of -LVmsTmBZ_kCdcXlZh7e.
FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference ref = mFirebaseDatabase.getReference().child("books").child("Classical Mechanics");
String key = ref.push().getKey();
Toast.makeText(book_details.this, key, Toast.LENGTH_SHORT).show();
Then I am using:
FirebaseDatabase.getInstance().getReference()
.child("books")
.child(Classical Mechanics)
.child(key)
.child("sellername")
.setValue("newvalue");
And it gives me null error which is expected outcome since I'm getting random keyvalue instead of single constant.
I'm using below code but I"m getting different key value each time randomly
instead of -LVmsTmBZ_kCdcXlZh7e.
This is happening because everytime you are using the push() method a brand new id is generated.
So if you want to access specific objects, you must know something that unique identifies those objects. In this case, if want you to change the value of your sellername property, you should use a query that looks like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference classicalMechanicsRef = rootRef.child("books").child("Classical Mechanics");
Query query = classicalMechanicsRef.orderByChild("sellername").equalTo("sagar");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
ds.child("sellername").getRef().setValue("newvalue");
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
query.addListenerForSingleValueEvent(valueEventListener);
Using this code, you'll change the name of the seller within all objects, which makes sense since the new name must exist within all objects.
Edit: It's even simpler to update/delete the data under a single object. For that please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference classicalMechanicsRef = rootRef.child("books").child("Classical Mechanics").child("-LVmsTmBZ_kCdcXlZh7e");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dataSnapshot.child("sellername").getRef().setValue("newvalue");
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
classicalMechanicsRef.addListenerForSingleValueEvent(valueEventListener);

How can I populate an ExpandableListView child views through Firebase database?

I want to populate my expandable list view with the values from Firebase database. I am able to add data to views statically but through Firebase not.
This is my code for that:
public class ExpandableListitems {
public List<String> food;
public HashMap<String, List<String>> getData() {
final HashMap<String, List<String>> expandableListDetail = new HashMap<String, List<String>>();
//getting fooditems from database
FirebaseDatabase firebaseDatabasefighter = FirebaseDatabase.getInstance();
DatabaseReference databaseReferencefighter = firebaseDatabasefighter.getReference("food").child("food_details");
ValueEventListener valueEventListenerfighter = new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
food = new ArrayList<String>();
String value = String.valueOf(ds.getValue());
food.add(value);
Log.i("vipan",value);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
databaseReferencefighter.addValueEventListener(valueEventListenerfighter);
food.add("milk");
food.add("dahi");
food.add("paratha");
food.add("aaloo");
expandableListDetail.put("FoodItems", food);
return expandableListDetail;
And my database looks like this:
food
food_details:
"2% Fat Milk"
i want to add this food_details value into the listview's view but unable so far.How can i implement this?
You cannot return something now that hasn't been loaded yet. With other words, you cannot simply return the expandableListDetail HashMap<String, List<String>> which contains a list of strings that is coming from the database as a result of a method because this list will always be empty due the asynchronous behaviour of this method. This means that by the time you are trying to return that result, the data hasn't finished loading yet from the database and that's why is not accessible.
A quick solve for this problem would be to use the food list only inside the onDataChange() method, otherwise 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.

how to get combined data of 2 nodes using a single for each loop with same dtasnapshot object

I need to display list of all users (Name, date and status) in a single list where status="Leave Pending" as pointed by red arrow. I wrote the following code to do this but it is not giving me username in the list.
As I used nested for each loop for this but not getting username. Kindly suggest me some solution to display the username too.
In my code:
LeaveRequestsInfo is the model class for mapping data.
requestsInfo is the object of modal class in which i am mapping my data.
listViewRequests is the ListView
requestsList is the object of List
To solve this, you need to query the database twice, once to get the user id and second, based on that id to get the name of the user. This can be done in a very simple way, using the String class, so please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference attendanceRef = rootRef.child("Attendance");
Query query = attendanceRef.orderByChild("status").equalsTo("Leave Pending");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String id = ds.child("id").getValue(String.class);
DatabaseReference idRef = rootRef.child("Users").child(id);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue(String.class);
Log.d("TAG", name);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
idRef.addListenerForSingleValueEvent(eventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(valueEventListener);
The result in your logcat will be all the names of all attendances where the status is Leave Pending.

Android- Firebase How to assign a child value under each ArrayList value?

I am trying to make an event sorter app. I'm trying to grab the friends arraylist from the database, and add the event_key under each friend value in the database.
final ArrayList<String> friends= new ArrayList<String>();
hello.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dsp : dataSnapshot.getChildren()) {
friends.add(String.valueOf(dsp.getKey()));
}
mDatabaseUserEvents.child(invited_list).child(event_key).setValue(true);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
However, I get an error saying that ArrayList is not compatible.
The database structure I am trying to aim for is this:
Events:
-User1:
-event_key:true
-User2:
-event_key:true
I am pretty sure I need to use a for loop, but confused on how to achieve it. Thanks!
Because Firebase is a NoSQL database, it is structured as pairs of key and values. So every child is a Map and not an ArrayList. It's true that you can get a value from the database and store into an ArrayList but not in the way you do, because of the asynchronous behaviour of onDataChange() method, your friends ArrayList will always be empty. This is happening because onDataChange() method is called even before you are trying to add those values to that ArrayList.
If you want to set true for all the event_key coresponding to each user and assuming that Events node is a direct child of Firebase-database, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference eventsRef = rootRef.child("Events");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userKey = ds.getKey();
Log.d("TAG", userKey);
eventsRef.child(userKey).child("event_key").setValue(true);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
eventsRef.addListenerForSingleValueEvent(eventListener);

Categories

Resources