Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to add data to a list in Firebase Realtime Database

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.

  1. Read the database childreference
  2. get the datasnapshot and check if it is null (which means first time)
  3. if it is null, directly set your local list
  4. 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

  5. now the local list contains all the items in remote as well as new items. save this to the child reference

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

enter image description here

like image 340
doe Avatar asked Oct 09 '18 10:10

doe


Video Answer


1 Answers

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.

like image 134
Alex Mamo Avatar answered Sep 20 '22 03:09

Alex Mamo