function to check if a value exists in firebase database (variable needs to be final or effectively final)

Viewed 31

I need a function that checks if a value exists or not in my firebase realtime database. I tried to write the code below:

    public boolean esiste(String desc, DatabaseReference meseref){

        boolean exists = false;
        meseref.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if(snapshot.child(desc).exists()){
                    exists = true;
                }
            }

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

            }
        });

        return exists;
    }

Maybe it is not the best way, but it is seems very simple for me (I am not an expert programmer). The problem is that compiler says that "Variable 'exists' is accessed from within inner class, needs to be final or effectively final", and I have an error.

So, how can I make a function that checks if the value exists or not?

Thank you so much

1 Answers

You have two separate problems, the compiler error and a conceptual error. To get your desired result, you need to restructure the code to fix the conceptual error, but you should also try to understand the compiler error in the existing code.

For the compiler error, see the explanation of effectively final variables in anonymous inner classes in this question.

(You didn't provide imports in your example, so I am guessing about the framework you are using in the links I provide below).

For the conceptual error, according to the documentation, the purpose of the addListenerForSingleValueEvent method is to register a listener that will be notified (asynchronously, i.e., in another thread) if the value referred to by the DatabaseReference changes. Even if your code compiled, registering the listener would return immediately, and the value of your exists variable would depend on whether the listener happened to update the value of the variable in the very short time before your code reached the return statement.

Instead, you need to check the value directly. For this, I think you need the get method. This method is also asynchronous, but works differently. It gives you a Task, and you need to wait for the Task to complete (using the Tasks.await) before retrieving its value.

The code should look something like this:

    public boolean esiste(String desc, DatabaseReference meseref){

        Task<DataSnapshot> task = meseref.get();
        DataSnapshot dataSnapshot = Tasks.await(task);
        return snapshot.child(desc).exists();
    }
Related