0

I'm writing an android app using java. i have it connected to Realtime database. I'm trying to search my data and check if a certain key exists in it or not.

public boolean checkForKey(String key) {
    final boolean[] found = {false};
    ValueEventListener listener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            for (DataSnapshot dataSnapshot: snapshot.getChildren()){
                if(dataSnapshot.getKey().equals(key)) {
                    found[0] = true;
                }
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
        }
    };
    dbRef.child("Polls").addValueEventListener(listener);
    return found[0];
}

The function is returning false before it finishes the part of the code that actually searches through the database. Any help in explaining why does this happen is appreciated.

moustafa
  • 27
  • 5
  • What "function" (method) exactly are you talking about? – Turing85 Apr 23 '22 at 17:54
  • @Turing85 the one i have the code for (checkForKey()), i used it in my main and always returning false. – moustafa Apr 23 '22 at 17:58
  • Method `checkForKey` does not do any searching. Method `onDatachanged(...)` (which I assume performs the search you are talking about) isn't executed immediately, but only when it is called by `dbRef`. – Turing85 Apr 23 '22 at 17:59
  • @Turing85 yeah I know, but i mean this whole method is always returning false. As i was debugging the problem, i log.d before the return statement and after setting found[0] to true. It was printing the one before the return value before the other one. – moustafa Apr 23 '22 at 18:04
  • As I said: when method `checkForKey(...)` is called, method `onDatachanged(...)` is not executed, but registered as callback/listener on `dbRef`. This behaviour is expected. The observed behaviour is expected. – Turing85 Apr 23 '22 at 18:08
  • @Turing85 ohh i get it now, how do i go about solving it ? should i just put the Searching part of code in my main? – moustafa Apr 23 '22 at 18:11
  • Does this answer your question? [Why does my function that calls an API return an empty or null value?](https://stackoverflow.com/questions/57330766/why-does-my-function-that-calls-an-api-return-an-empty-or-null-value). Try using [LiveData or a different code pattern](https://stackoverflow.com/a/70178210/9473786) that doesn't require returning the result immediately from your function. – Tyler V Apr 23 '22 at 18:21
  • Firebase API is asynchronous. So please check this [answer](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method/47853774) to see how can you solve this using a callback. You might also be interested in reading this article, [How to read data from Firebase Realtime Database using get()?](https://medium.com/firebase-tips-tricks/how-to-read-data-from-firebase-realtime-database-using-get-269ef3e179c5). – Alex Mamo Apr 24 '22 at 07:25

1 Answers1

1

From the docs:

onDataChange: This method will be called with a snapshot of the data at this location. It will also be called each time that data changes.

When the data changes, whatever is inside the method will be executed. In other words, the method onDataChange instructs the program what to do when it gets results (which could be whenever)

This is asynchronous behaviour - as @Turing85 points out, this will only be called when the data changes.

If you want to know if something with this key exists, you could construct a query and then call get() method which would return a Task<DataSnapshot>. For this task, you could attach addOnCompleteListener listener to do what you would like. This would also be asynchronous, so it would only run when there is a result.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
ferrouskid
  • 466
  • 2
  • 7