Problem in recovering data from firebase

Asked

Viewed 541 times

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 recovering the data within a function. The problem in question is that to recover database data in firebase it is necessary to create a ValueEventListener implementing the methods onDataChange and onCancelled and within the method onDataChange recover the data using the type variable DataSnapshot. The problem is that I cannot assign the result of the method getValue() to my variable usuario created outside the method OnDataChange. If I create the variable within the method, it works smoothly, but with the variable outside I can’t do the assignment. I believe this is caused because the methods are executed asynchronously (I think). Would anyone know any way I could do this assignment? Because I need this variable to perform other tasks in my app. The code referred to 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;
    }

}
  • Is there any way to place the section where you assign mDatabase? I believe the problem is in the reference, but without the attribution I can’t say.

  • @Grupocdsinformática sorry for the delay, I was traveling and only came back this week. I just edited the question with the code snippet you requested.

  • No problem. It may be that the userid was not put as key. So it may be coming null. Take a look at the Firebase structure if the key of the key is equal. Also try instead of using as Child, point the reference directly to key

  • @Grupocdsinformática I think I ended up explaining my problem in the wrong way. The problem is not that the user reference is being null, the problem is that the Android Studio IDE itself mentions that there is a syntax error in the code. Basically, it shows syntax error saying that the user variable does not exist. It is as if what is inside the onDataChange do not "see" the outside scope, which in this case is where the variable is being created. I tried to put the modifier final in the variable declaration, but still with the same problem. Do you have any idea what might be?

  • Sets the user variable to a global of the class. See if it solves.

2 answers

0

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

public class FireBaseDB{

    private DatabaseReference mDatabase;
    private Usuario usuario;

But you’ll have another problem: Firebase read methods happen asynchronously (in another Thread). So the moment you do the return usuario, this variable has not yet been initialized.

So I nay recommend to create a class(Firebasedb) only to read from the database. Read directly in your Activity or Fragment.

-1

This problem can be solved in several ways. The one that I most use is the following: As I can’t control the asynchronous listener, so I try to turn it into synchronous, ie 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 receive 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 kind of primitive data storage is very simple to use and in no trouble will come to be a problem for you, at least for me, it just 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’ve helped!

Browser other questions tagged

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