0

I'm trying to store multiple lists of locations inside my database. I want the keys to follow a pattern, like "LocationList 1 ", "LocationList 2" and so on.

For that I created a list to hold all the keys. First I want to check if there are any children in the database. If there are none, I want to add a child called "LocationList 1" and store that string in my list. If there's already a child with that name (meaning my list's size is not 0), then I want to add a key with the name "LocationList <number of items in list here + 1>". But something in my logic is wrong because the list size is always 0.

Here's my method for retrieving all keys:

    private void getKeysList() {

        databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {

                if(snapshot.hasChildren()) {
                    locationKeysString.add(snapshot.getKey());;
                }

            }

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

            }
        });
    }

Here's my method for adding a location list to database:

public Task<Void> addLocation(List<Location> locationList, Context context) {

        getKeysList();
        int itemNumber = locationKeysString.size();
        String keyValue = new String();
        Task<Void> task;

        if (itemNumber == 0) {
            keyValue = "LocationList " + 1;
            locationKeysString.add(keyValue);
            task = databaseReference
                    .child(keyValue)
                    .setValue(locationList)
                    .addOnSuccessListener(new OnSuccessListener<Void>() {
                        @Override
                        public void onSuccess(Void unused) {
                            Toast.makeText(context, R.string.add_to_database_success, Toast.LENGTH_SHORT).show();
                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Toast.makeText(context, R.string.add_to_database_failure, Toast.LENGTH_SHORT).show();
                        }
                    });
        } else {
            keyValue = "LocationList " + (itemNumber + 1);
            locationKeysString.add(keyValue);
            task = databaseReference
                    .child(keyValue)
                    .setValue(locationList)
                    .addOnSuccessListener(new OnSuccessListener<Void>() {
                        @Override
                        public void onSuccess(Void unused) {
                            Toast.makeText(context, R.string.add_to_database_success, Toast.LENGTH_SHORT).show();
                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Toast.makeText(context, R.string.add_to_database_failure, Toast.LENGTH_SHORT).show();
                        }
                    });
        }

        return task;
    }

But when I run my application it keeps adding locations to a single location list in the database, "LocationList 1": enter image description here

"LocationList 2" is never created.

I've also tried the following:

    private void getKeysList() {
        
        databaseReference.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
                
                locationKeysString.add(snapshot.getKey());
            }

           [...]);
    }

But list size is still 0.

What am I doing wrong? And besides that, is there some way I can improve my code?

Thank you.

Edit: Those two methods, getKeysList() and addLocation() are the only places in my code where I refer to my locationKeysString list at all.

Other than that I call addLocation() only once in my onStop() method of my main activity:

@Override
    protected void onStop() {
        super.onStop();

        MyLocation myLocation = (MyLocation) getApplicationContext();
        locationList = myLocation.getLocationList();

        DAOLocation daoLocation = new DAOLocation();
        daoLocation.addLocation(locationList, this);
    }
Laila Campos
  • 801
  • 1
  • 8
  • 21
  • I'm not 100% certain, but I strongly suspect you are checking the list size before `onChildAdded` or `onDataChange` has been called. Data is loaded from Firebase asynchronously, and that means you have to carefully check the flow of the code. Any code that needs the data from the database needs to be inside the callback, or be called from there. I recommend checking https://stackoverflow.com/questions/50434836/getcontactsfromfirebase-method-return-an-empty-list/50435519#50435519 and https://stackoverflow.com/questions/33203379/setting-singleton-property-value-in-firebase-listener for more info – Frank van Puffelen Dec 03 '21 at 19:50
  • The first answer says to put all code that returns the list into the onDataChange method. As far as I know, I'm doing that, right? – Laila Campos Dec 03 '21 at 20:00
  • That's what's not clear to me. In the first snippet: all code that **uses** the data from the database needs to be inside the `onDataChange`. It's unclear to me when "the list size is always 0" happens in relation to that code, but since you never use the list in `onDataChange`, I suspect that you are using it elsewhere, at a moment that the `onDataChange` hasn't run yet. – Frank van Puffelen Dec 03 '21 at 21:47
  • Please show us the code where you are checking the size of the list. – Alex Mamo Dec 04 '21 at 09:48
  • Those two methods are the only places in my code where I refer to my `locationKeysString` list at all. The second method, `addLocation`, is where I check the list size. Other than that I call that same method only once, inside the `onStop()` method of my main activity. – Laila Campos Dec 04 '21 at 12:16

0 Answers0