Wait for the results of asynchronous methods of Firebase

1

I'm often having problems with several code snippets where I need to call asynchronous methods from the Firebase Database library.

The point is that these methods often do not return their results before the View is loaded, and in some cases, these results are required to properly load elements for the app to run.

Here's an example:

public void validarLogin() {
    autenticacao = ConfigFirebase.getFirebaseAutenticacao();
    autenticacao.signInWithEmailAndPassword(
            usuario.getEmail(),
            usuario.getSenha()
    ).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            if(task.isSuccessful()) {

                id_user_logado = Base64Custom.codificarBase64(usuario.getEmail());

                firebase = ConfigFirebase.getFirebase().child("usuario").child(id_user_logado);
                valueEventListener = new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        // Salvando usuário logado nas preferêncais
                        Usuario usuario_recuperado = dataSnapshot.getValue(Usuario.class);

                        Preferencias preferencias = new Preferencias(LoginEmailActivity.this);
                        preferencias.salvarPreferencias(id_user_logado, usuario_recuperado.getNome());
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                };

                firebase.addListenerForSingleValueEvent(valueEventListener);

                Toast.makeText(getApplicationContext(), "Bem-vindo!", Toast.LENGTH_LONG).show();
                abrirTelaPrincipal(); // Uma Intent que chama outra Activity
            } else {
                Toast.makeText(getApplicationContext(), "E-mail ou senha inválidos!", Toast.LENGTH_LONG).show();
            }
        }
    });
}

In the above case, I confirm user authentication in Firebase, this is confirmed, and the Toast of "Welcome" is loaded . However, by the time the OpenTab () method is called, the addListenerForSingleValueEvent (valueEventListener) method has not yet consulted. In this way, my other Activity is loaded before the completeness of my asynchronous method , causing the instructions that are inside this not to be executed.

Sometimes without the data in this method, my application will add up problems in synchronous methods.

The question is: What is the most appropriate way to ensure that Firebird's asynchronous method returns are received before the application follows its flow without this data?

    
asked by anonymous 17.02.2018 / 23:55

1 answer

1

Your toast and intent should be called within the onDataChange, which is the moment you have all the necessary information.

 preferencias.salvarPreferencias(id_user_logado, usuario_recuperado.getNome());

You should call after this line.

You'll probably need to use runOnUiThread you can find an example here .

Why is it necessary to call within onDataChange ? As you yourself said it is an asynchronous method or it takes a while to get a response (make a request to the firebase server and wait for it to respond).

What you should do is put some "wait" message ( loading ) and force the user to wait for the Firebase request.

    
18.02.2018 / 02:21