Can't Get Values Out of Ondatachange Method

How can I get the values out of onDataChange method?

You can't get the value out of the callback. Well... technically you can get it out, but you can't know when that happens.

Instead what you should do is move the code that does the comparison into the onDataChange() callback. E.g.

final String emailFromUser = "pc@somedomain.com";
usersListDatabaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot emailSnapshot: dataSnapshot.getChildren()) {
String emailFromDatabase = emailSnapshot.getValue(String.class);
if (emailFromDatabase.equals(emailFromUser)) {
System.out.println("Found a matching email");
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});

To make the code more reusable, you can create a custom callback interface. For more on that, see getContactsFromFirebase() method return an empty list

How can I get data out of onDataChange method?

You cannot assign a final variable a new value.

And if you are gonna access outer class variables inside inner class they have to declared final.

One simple but not elegant way is to declare an boolean array of size 1.

mDatabaseReference = mFirebaseDatabase.getReference("Executive Branch");
final String newUrl = url;
final boolean[] bool = new boolean[1]; //boolean array of size 1

mDatabaseReference.limitToFirst(1).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getChildrenCount() > 0) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
ExecutiveOrder executiveOrder = snapshot.getValue(ExecutiveOrder.class);
if (executiveOrder.getUrl().equals(newUrl)) {
bool[0] = true; //access the bool value like this
} else {
bool[0] = false;
}
}
}
}

@Override
public void onCancelled(DatabaseError databaseError) {
Log.e("Executive Order", "The read failed: " + databaseError.getDetails());
}
});

By the way you are making a big mistake. Your code is gonna return false all the time.

Firebase database methods are Asynchronous meaning they are executed in a separate thread so we cannot determent when they data will be retrieved from the database. It depends upon the speed of your internet.

So you have to call the appropriate method inside the onDataChange method. Example ...

private boolean compare(String url) {
mDatabaseReference = mFirebaseDatabase.getReference("Executive Branch");
final String newUrl = url;

mDatabaseReference.limitToFirst(1).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getChildrenCount() > 0) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
ExecutiveOrder executiveOrder = snapshot.getValue(ExecutiveOrder.class);
boolean bool = executiveOrder.getUrl().equals(newUrl);
doSomething(bool); //This method will handle the logic
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e("Executive Order", "The read failed: " + databaseError.getDetails());
}
});
}

How to get arrayList value outside of onDataChange method so that it doesnt activate startActivity

Its a simple trick, you can use a Handler and check list data before post-runnable.

     final List<User> list = new ArrayList<>();
holder.cont.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
rootRef.child("users").child(mAuth.getUid()).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
user = ds.getValue(User.class);
list.add(user);
}
}

@Override
public void onCancelled(@NonNull DatabaseError databaseError) { }
});
Handler handler = new Handler();
int delay = 1000; //milliseconds

handler.postDelayed(new Runnable(){
public void run(){
if(!list.isEmpty())//checking if the data is loaded or not
{
Intent intent = new Intent(getApplicationContext(), StoryActivity.class);
Bundle extras = new Bundle();
extras.putInt("PROJECT_ID", position);
extras.putInt("STORY_POSITION",
list.get(position).getPosition());
extras.putInt("STORY_ID", model.getPosition_on_tree());
extras.putInt("CHAPTER_SIZE", model.getChapter_size());
intent.putExtras(extras);
startActivity(intent);
finish();
}
else
handler.postDelayed(this, delay);
}
}, delay);
}
});

The code will only execute when the data is fetched from firebase.

want to use onDataChange variable data below the event listener

You cannot simply use that value outside onDataChange() method because this method is called asynchronous. This means that is called before you are getting the data from the database. The simplest way would be to use that value only inside the onDataChange() or a more complex way would be to dive into asynchronous world and use that value outside. For that, please see my answer from this post: How To Get Value Async In Outside Method onDataChange().



Related Topics



Leave a reply



Submit