1

I want to add another item to the "oreSelectate" list from my Firebase but I don't know how. I want to select another hourly interval from the app and add it to the "oreSelectate" list.

This is my app App

This is what I have in my Firebase Realtime Database. My firebase

I've tried 3 things:

  1. setValue() - it doesn't work because it will overwrite the existing data
  2. I've tried loading the firebase data in a List and then copy the firebase list to another list and add the new data to the second list and then adding that list to the child "oreSelectate" but the problem is that it keeps the old data and puts the new data like this New firebase data
  3. I've tried deleting the old data from firebase after loading it in a List but it still doesn't work

What seems to be the problem? I'll leave my code below:

btn_inchiriaza.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getOreFromFirebase(new OreListCallback() {
                    @Override
                    public void onCallback(List<String> value) {
                        ore_ocupate.clear();
                        ore_ocupate = value;
                        int len = lv_ore.getCount();
                        SparseBooleanArray checked = lv_ore.getCheckedItemPositions();
                        for(int i = 0; i < len ; i++){
                            if(checked.get(i)){
                                ore_ocupate.add((String) oreAdapter.getItem(i));
                            }
                        }
                        reff.child("TerenuriFotbal").child("Sector " + cifra_sector).child(nume_teren_extra).child("oreSelectate").setValue(ore_ocupate);
                        lv_ore.clearChoices();
                        oreAdapter.notifyDataSetChanged();

                        Toast.makeText(view.getContext(), "Ati rezervat cu succes!", Toast.LENGTH_LONG).show();
                        Intent intent = new Intent(InchiriazaTeren.this, MainActivity2.class);
                        startActivity(intent);
                    }
                });
            }
        });
public interface OreListCallback{
        void onCallback(List<String> value);
    }

    public void getOreFromFirebase(final OreListCallback myCallback){
        reff.child("TerenuriFotbal").child("Sector " + cifra_sector).child(nume_teren_extra).child("oreSelectate").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                    for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                        String ora = (String) dataSnapshot.getValue();
                        assert ora != null;
                        ore_ocupate_baza_de_date.add(ora);
                    }
                    myCallback.onCallback(ore_ocupate_baza_de_date);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });
    }

Thanks!

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193

2 Answers2

1

As I see in your screenshot, your "oreSelectate" property is of type array. Unlike in Cloud Firestore, where working with arrays is quite easier, in the Realtime Database, there are some constraints. One of the reasons why many developers don't use arrays is because it makes the security rules hard to write. A better approach, in this case, would be to model your database as below:

Firebase-root
  |
  --- TerenuriFotbal
        |
        --- Sector 3
              |
              --- Asii Sport
                   |
                   --- oreSelectate
                          |
                          --- "10:00 - 11:00": true
                          |
                          --- "11:00 - 12:00": true
                          |
                          --- //Other properties

In this way, you can simply add a new element in the Map, as "oreSelectate" is now a Map and not an array, by simply creating a reference that points to "oreSelectate" node and use DatabaseReference's updateChildren() method. Besides that, you can also simply change the value of a single child, from true to false and display the new availability in the UI, without the need to read the entire array on the client.

For a better understanding, I recommend you read Frank van Puffelen's excellent answer from the following post:

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
0

Firebase Database uses primitive and String types for values. This means your List is always a String. The only way to add some information to this form of list is to get it as a String, using ValueEventListener and then adding a value like in List.

For performing IO Operations in Firebase Database

Cloud Firestore is much better for storing different types of objects. In Firestore you have the ability to choose between:

number, boolean, String, Map, geopoint, Array, timestamps and even references to other values.

This allows you to do your operations.

How to add data in Firestore