Problem in recovering data from firebase

0

I recently started working with Firebase and am still learning what can be done by reading the available documentation. But one problem I'm having is in recovering the data inside a function. The problem in question is that to recover data from the database in the firebase it is necessary to create a ValueEventListener that implements the onDataChange and onCancelled methods and within the onDataChange method retrieve the data using the variable of type DataSnapshot . The problem is that I can not assign the result of the getValue() method to my usuario variable created outside the OnDataChange method. If I create the variable inside the method, it works without problems, but with the variable out I can not do the assignment. I believe this is caused because the methods run asynchronously (I think). Would anyone know of any way I could do this assignment? I need this variable to perform other tasks in my app. Here is the code below:

public class FireBaseDB{

    private DatabaseReference mDatabase;

    public FireBaseDB(){
        mDatabase = FirebaseDatabase.getInstance().getReference();

    }

    public Usuario recuperarUsuarioDoBanco(String userId){

        mDatabase.child("users").child(userId);
        Usuario usuario;

        ValueEventListener listener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                usuario = dataSnapshot.getValue(Usuario.class); //não funciona

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.w(TAG, "Ação Cancelada", databaseError.toException());

            }
        };
        mDatabase.addValueEventListener(listener);

        return usuario;
    }

}
    
asked by anonymous 03.11.2017 / 11:07

2 answers

0

For IDE not to show the syntax error, you just need to declare the usuario variable globally in the class, rather than declaring locally in the method:

public class FireBaseDB{

    private DatabaseReference mDatabase;
    private Usuario usuario;

But you will have another problem: Firebase reading methods happen asynchronously (on another Thread). So by the time you return usuario , this variable has not yet been initialized.

So, I do not recommend creating a class (FireBaseDB) just to read from the database. Read directly into your Activity or Fragment.

    
24.02.2018 / 18:06
-1

This problem can be solved in several ways. The one I use the most is the following: As I can not control the asynchronous Listener, I soon try to turn it into synchronous, that is, to control it. I do exactly the following.

public class FireBaseDB{

    private DatabaseReference mDatabase;

    public FireBaseDB(){
        mDatabase = FirebaseDatabase.getInstance().getReference();

    }

    public Usuario recuperarUsuarioDoBanco(String userId){

        mDatabase.child("users").child(userId);
        Usuario usuario;

        ValueEventListener listener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
            //Alimento o meu objeto
            usuario = dataSnapshot.getValue(Usuario.class); 

            //E utilizo outra classe para "controlar" as informações do objeto
            UsuarioSPref usuario_sp = new UsuarioSPref();

        obj_Anuncios_sp.saveSP(objFirebaseAnuncios);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.w(TAG, "Ação Cancelada", databaseError.toException());

            }
        };
        mDatabase.addValueEventListener(listener);

        return usuario;
    }

}

And in my next class I use the SharePreference class to store the information I get from the object Example:

public class UsuarioSPref {
    //LibraryIO é a classe com diversos método do sharePreference que crie.
    private LibraryIO io = new LibraryIO(MyApplication.getAppContext());
    private String[] telaPrincipal = {"telaPrincipalNome", "telaPrincipalUrl", "telaPrincipalCliques", "telaPrincipal_imgUrl"};


    public boolean saveSP(ObjAnuncios objFBparametro) {

        Log.i("LINK_URL", "Método saveSP foi chamadao, listener de anúncios funcionando");

        io.setStringIO(telaPrincipal[0], objFBparametro.getNome());
        io.setStringIO(telaPrincipal[1], objFBparametro.getUrlWebPag());
        io.setIntIO(telaPrincipal[2], objFBparametro.getNumeroCliques());
        io.setStringIO(telaPrincipal[3], objFBparametro.getImgUrl());

        return true;
    }


}

This class of primitive storage is very simple to use and no problem will ever be a problem for you, at least for me, it only helps me. So you can get these values whenever you want without worrying about Listener and you can get the data offline.

I hope I have helped!

    
23.06.2018 / 17:40