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
How to Make Custom Dialog with Rounded Corners in Android
How to Use the Paid Version of My App as a "Key" to the Free Version
Swiperefreshlayout Setrefreshing() Not Showing Indicator Initially
Creating a Softkeyboard with Multiple/Alternate Characters Per Key
Understanding Recyclerview Sethasfixedsize
Why Do I Want to Avoid Non-Default Constructors in Fragments
How to Center Icon and Text in a Android Button with Width Set to "Fill Parent"
Adb Install Fails with Install_Failed_Test_Only
Write Android Logcat Data to a File
Programmatically Change Input Type of the Edittext from Password to Normal & Vice Versa
Returning from an Activity Using Navigateupfromsametask()
Android, Make an Image at a Url Equal to Imageview's Image
Wrap_Content View Inside a Constraintlayout Stretches Outside the Screen
How to Export Library to Jar in Android Studio
How to Use an Arrayadapter in Android of Custom Objects