0

I'm gettig a error that my variable inside the Listener display the correct value, but when it leaves it's just an empty variable.

if (i.getStringExtra("where").equals("login")){
        email = i.getStringExtra("email");
        db.collection("users").whereEqualTo("email", email).get()
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        for (DocumentSnapshot document : task.getResult()) {
                            name = document.getString("name");
                            Log.d("username", name);
                        }
                    }
                });
    }else{
        //anything
    }
    Log.d("username", name);
    userName.setText(name);

The Log inside of the Listener returns the correct value, and the outsider giver a null pointer excpetion println needs a message. Tried to use this.name instead of just name, still did not work.

UPDATE

i give the variable name a value before enter the if condition, and notice that the Log.d that is outside of the if prints first the older value, and then the Log.d that is inside if prints the correct value:

2021-02-05 13:29:06.791 27900-27900/com.example.pomodorotasks D/username: teste

2021-02-05 13:29:09.020 27900-27900/com.example.pomodorotasks D/username: Rafael Alves

"teste" older value "Rafael Alves" the value that name receive inside of listener

It seems that it take a time to the listener do what it need to do, i don't know.

  • 1
    Does this answer your question? [wait until firebase retrieves data](https://stackoverflow.com/questions/30659569/wait-until-firebase-retrieves-data) – Methkal Khalawi Feb 16 '21 at 09:17

1 Answers1

0

SOLVED

By this comment https://stackoverflow.com/a/42811962/15148029

Don't use Firebase as functions that return values - it goes against it's asynchronous nature.

Plan code structure that allows Firebase to perform it's task and then within the closure (block) go to the next step.

In your code, for example, change the function to not return anything and within the onDataChange, as the last line call the next function to update your UI.


Didn't know about this detail of async function.

  • Let's avoid an incorrect assumption; While this statement is correct *Don't use Firebase as functions that return values*, the code in the question *doesn't do that*, there is no returned data, so this answer doesn't apply to your question. The actual issue is that the code following the closure *Log.d("username", name);* will run BEFORE the code in the closure so therefore it doesn't appear to be populated when it executes. However, it is populated once the code in the closure runs. Moving that code and this `userName.setText(name);` right after `name = document.getString("name");` will work. – Jay Feb 16 '21 at 18:33