I'm using firebase realtime db, and I'm storing a list of string in a particular storage reference. Currently, to add something to the list
I'm doing the following steps.
if dataSnapshot.getValue();
not null then (already data present in
the db, so need to append the new data to th e end of it.)
save the remote list from dataSnapshot.getValue();
to a local variable.
then add the new data to the end of it
Below is the code I have written for that
DatabaseReference reference = root()
.child(userId)
.child(list_id);
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
reference.removeEventListener(this);
List<String> value = new ArrayList<>();
if (dataSnapshot.getValue() == null) {
value.add(message);
} else {
if (dataSnapshot.getValue() instanceof List && ((List) dataSnapshot.getValue()).size() > 0 && ((List) dataSnapshot.getValue()).get(0) instanceof String) {
value = (List<String>) dataSnapshot.getValue();
value.add(message);
}
}
reference.setValue(value, (databaseError, databaseReference) -> {
finish();
});
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
finish();
}
private void finish() {
Log.e(TAG,"save finished");
}
});
Thats a lot of steps to do a simple operation. Also , all the time I'm pulling the whole data from remote and appending the new data to it.
is there any easy way to do this? I tried with the 'push()' method as follows
DatabaseReference reference = root()
.child(userId)
.child(list_id).push();
But it adds a new key always to the value I add. Can anyone explain what is the proper way to do it with less code?
UPDATE:
My db structure is as shown below
The solution you gave it's very good but why to remove the listener inside the callback? I'll write you the code to be more simpler. Please see it below:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference listIdRef = rootRef.child("list").child(list_id);
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> list = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String comment = ds.getValue(String.class);
list.add(comment);
}
//Do what you need to do with your list
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
listIdRef.addListenerForSingleValueEvent(valueEventListener);
Don't ignore errors.
The simplest way in which you can add a new child in your 08-10-18
node, without the need to get the enitire list, would be using only the following lines of code:
Map<String, Object> map = new HashMap<>();
map.put("5", "comment55");
rootRef.child("list").child(list_id).updateChildren(map);
But even a better solution would be to use instead of lists, maps and the children should be added using the push()
method. So your database structure should look like this:
Fireabase-root
|
--- usr100
|
--- 08-10-18
|
--- randomId: "comment1"
|
--- randomId: "comment2"
|
--- randomId: "comment3"
|
--- randomId: "comment4"
And the code should look like this:
String key = rootRef.child("list").child(list_id).push().getKey();
Map<String, Object> map = new HashMap<>();
map.put(key, "comment5");
rootRef.child("list").child(list_id).updateChildren(map);
In this case you don't have to worry about the key, which is not a number anymore. Without the help of the push()
method, you need to get the entire list, as explained in the first part of my answer, add the new element and the update the list in the database.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With