Wait for the results of asynchronous Firebase methods

Asked

Viewed 562 times

1

I am frequently having problems in various code snippets where I need to call asynchronous methods from the Firebase Database library.

The issue 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.

Follow 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, at the time when the method open() is called, the addListenerForSingleValueEvent(valueEventListener) not yet made the query. This way, my other Activity is loaded before the completeness of my asynchronous method, causing the instructions within this to not be executed.

Sometimes, without the data of these methods, my application adds problems in the synchronous methods.

The point is: what is the most appropriate way to ensure that the returns of asynchronous Firebase methods are received before the application follows its flow without this data?

1 answer

1

Your Toast and the Intent must be called inside the onDataChange, which is the moment you have all the necessary information.

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

You should call after that line.

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

It is necessary to call inside the onDataChange? As you said yourself, it’s an asynchronous method, meaning 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 message waiting(loading) and force the user to wait for the request to Firebase.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.