Reputation: 1399
I am getting a null pointer exception (have tested 1 instead of i here)
This is the method
public String getLat(int i) {
fillDriverList();
arrayLat.get(i);
return"0.000";
}
This is where it is called from in separate activity
AdminActivity appState = new AdminActivity();
latString = appState.getLat(i);
Here is the fill method, which is printing out the drivers names so appears to be filling the list, but then is null for some reason in my getLat method??
public void fillDriverList() {
//Creating firebase object
Firebase ref = new Firebase(Config.FIREBASE_URL);
//adding a value event listener so if data in database changes it does in textview also not needed at the minute
ref.child("Driver").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
arrayLat = new ArrayList<String>();
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Driver d = postSnapshot.getValue(Driver.class);
System.out.println("data snapshot Drivers name is -------------------> "+d.getName());
arrayLat.add(Double.toString(d.getLat()));
}
}
/************had to implement this method****************/
@Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
}
NOTE When I pass it like this
intent.putStringArrayListExtra("arrayLat", arrayLat);
there is no problem using it in the other actvity like this
arrayLat = I.getStringArrayListExtra("arrayLat");
Although the values I use then in the next activity are stored values and do not update when my information(latitude) in firebase changes.
Thanks
Upvotes: 0
Views: 619
Reputation: 2836
The problem that is visible through naked eye, is that, the list is being populated in a listener or callback, and you are treating the whole thing as synchronous. Look over here
ref.child("Driver").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
arrayLat = new ArrayList<String>();
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Driver d = postSnapshot.getValue(Driver.class);
System.out.println("data snapshot Drivers name is -------------------> "+d.getName());
arrayLat.add(Double.toString(d.getLat()));
}
}
/************had to implement this method****************/
@Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});
You are populating arrayLat inside onDataChange(DataSnapshot snapshot)
So, the fact is that since this is a callback the line arrayLat.get(i) is called even before the listener is fired and arrayLat is populated. Hope you got it. There are several ways to tackle this. You can create another interface to handle the callback or can directly write your code inside the callback. I will just write a simple solution. Change your code to this. First create an interface,
public interface SnapshotListener{
void onListFilled(ArrayList<String> arrayLat);
void onFailure();
}
public void getLat(int i, SnapshotListener listener) {
fillDriverList(listener);
//arrayLat.get(i);
//return"0.000";
}
Now change the other method to this.
public void fillDriverList(SnapshotListener listener) {
//Creating firebase object
Firebase ref = new Firebase(Config.FIREBASE_URL);
//adding a value event listener so if data in database changes it does in textview also not needed at the minute
ref.child("Driver").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
arrayLat = new ArrayList<String>();
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Driver d = postSnapshot.getValue(Driver.class);
System.out.println("data snapshot Drivers name is -------------------> "+d.getName());
arrayLat.add(Double.toString(d.getLat()));
}
if(listener != null){
listener.onListFilled(arrayLat);
}
}
/************had to implement this method****************/
@Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
if(listener != null){
listener.onFailure();
}
}
});
}
Now change
AdminActivity appState = new AdminActivity();
latString = appState.getLat(i);
to this
appState.getLat(i, new SnapshotListener{
public void onListFilled(ArrayList<String> arrayLat){
AdminActivity appState = new AdminActivity();
latString = arrayLat;
}
public void onFailure(){
//go crazy
}
});
The codes are directly written in SO, so there may be some syntax errors.
Upvotes: 1
Reputation: 735
Driver Object have to check it
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Driver d = postSnapshot.getValue(Driver.class);
if(d!=null ){
arrayLat.add(Double.toString(d.getLat()));
}
}
Upvotes: 0