How does an object return using addListenerForSingleValueEvent from fire base?

Asked

Viewed 173 times

2

Hello, I would like to know if it is possible returns an object using Query.addListenerForSingleValueEvent() from firebase, follow example code...

public static Passageiro getDadosUsuarioLogado() {
    DatabaseReference reference = ConfiguracaoFirebase.getFirebaseDatabase();
    Query query = reference.child("passageiros").orderByChild("id").equalTo(getIdentificadorUsuario()).limitToFirst(1);
    final Passageiro passageiro = new Passageiro();
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if(dataSnapshot.exists()){
                passageiro = dataSnapshot.getValue(Passageiro.class);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.d("getDadosUsuarioLogado: ", databaseError.getMessage());
        }
    });
    return passageiro;
}
  • Hello Joab! Could you be clearer? As you yourself did in the example code, the method getValue() class DataSnapshot, returns just one class object that you pass as parameter.

  • opa, I wonder how I do to returns the value outside the onDataChange method, because every time I call this method it returns me empty.

1 answer

0

When you call getDadosUsuarioLogado(), the return will always be null due to the call to the database being asynchronous. For you to get the returned object, do the following:

Create an interface:

public interface Observer<T> {
     void onEvent(T data);
}

We will use it to be notified when the object is finally returned. Then rewrite your method:

public static void getDadosUsuarioLogado(Observer<Passageiro> observer) {
    DatabaseReference reference = ConfiguracaoFirebase.getFirebaseDatabase();
    Query query = reference.child("passageiros").orderByChild("id").equalTo(getIdentificadorUsuario()).limitToFirst(1);

    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if(dataSnapshot.exists()){
                Passageiro passageiro = dataSnapshot.getValue(Passageiro.class);
                /* Aqui utilizamos a interface */
                observer.onEvent(passageiro);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.d("getDadosUsuarioLogado: ", databaseError.getMessage());
        }
    });
}

I modified your method so that we can obtain the object "asynchronously". I removed the return since we will not need more and also removed the creation of the passenger instance, since the getValue() returns a.

And finally, make your activity implement the interface to "observe" when the value "arrives":

public class NomeDaSuaActivity extends AppCompatActivity implements Observer<Passageiro> {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recipe);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        SuaClasse.getDadosUsuarioLogado(this) // Referência para a interface Observer
    }

    /* ... */

    public void onEvent(Passageiro data) {
       // Tá ai, faça o que você quiser com o objeto
    }
}

This is one of the best ways to get data asynchronously. I used this technique until a while ago when I started to migrate my project to new Android architecture components like Livedata, Viewlmodel and Repository. I hope this helps and any doubt just comment.

  • worked out, very obligatoooooooo

  • I am grateful to have helped you. Mark my answer as sure, it helps me =)

Browser other questions tagged

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